AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Spell Class Reference

#include "Spell.h"

Classes

struct  GOTargetInfo
 
struct  HitTriggerSpell
 
struct  ItemTargetInfo
 

Public Types

typedef std::set< Aura * > UsedSpellMods
 

Public Member Functions

 Spell (Unit *caster, SpellInfo const *info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID=ObjectGuid::Empty, bool skipCheck=false)
 
 ~Spell ()
 
void EffectNULL (SpellEffIndex effIndex)
 
void EffectUnused (SpellEffIndex effIndex)
 
void EffectDistract (SpellEffIndex effIndex)
 
void EffectPull (SpellEffIndex effIndex)
 
void EffectSchoolDMG (SpellEffIndex effIndex)
 
void EffectEnvironmentalDMG (SpellEffIndex effIndex)
 
void EffectInstaKill (SpellEffIndex effIndex)
 
void EffectDummy (SpellEffIndex effIndex)
 
void EffectTeleportUnits (SpellEffIndex effIndex)
 
void EffectApplyAura (SpellEffIndex effIndex)
 
void EffectSendEvent (SpellEffIndex effIndex)
 
void EffectPowerBurn (SpellEffIndex effIndex)
 
void EffectPowerDrain (SpellEffIndex effIndex)
 
void EffectHeal (SpellEffIndex effIndex)
 
void EffectBind (SpellEffIndex effIndex)
 
void EffectHealthLeech (SpellEffIndex effIndex)
 
void EffectQuestComplete (SpellEffIndex effIndex)
 
void EffectCreateItem (SpellEffIndex effIndex)
 
void EffectCreateItem2 (SpellEffIndex effIndex)
 
void EffectCreateRandomItem (SpellEffIndex effIndex)
 
void EffectPersistentAA (SpellEffIndex effIndex)
 
void EffectEnergize (SpellEffIndex effIndex)
 
void EffectOpenLock (SpellEffIndex effIndex)
 
void EffectSummonChangeItem (SpellEffIndex effIndex)
 
void EffectProficiency (SpellEffIndex effIndex)
 
void EffectApplyAreaAura (SpellEffIndex effIndex)
 
void EffectSummonType (SpellEffIndex effIndex)
 
void EffectLearnSpell (SpellEffIndex effIndex)
 
void EffectDispel (SpellEffIndex effIndex)
 
void EffectDualWield (SpellEffIndex effIndex)
 
void EffectPickPocket (SpellEffIndex effIndex)
 
void EffectAddFarsight (SpellEffIndex effIndex)
 
void EffectUntrainTalents (SpellEffIndex effIndex)
 
void EffectHealMechanical (SpellEffIndex effIndex)
 
void EffectJump (SpellEffIndex effIndex)
 
void EffectJumpDest (SpellEffIndex effIndex)
 
void EffectLeapBack (SpellEffIndex effIndex)
 
void EffectQuestClear (SpellEffIndex effIndex)
 
void EffectTeleUnitsFaceCaster (SpellEffIndex effIndex)
 
void EffectLearnSkill (SpellEffIndex effIndex)
 
void EffectAddHonor (SpellEffIndex effIndex)
 
void EffectTradeSkill (SpellEffIndex effIndex)
 
void EffectEnchantItemPerm (SpellEffIndex effIndex)
 
void EffectEnchantItemTmp (SpellEffIndex effIndex)
 
void EffectTameCreature (SpellEffIndex effIndex)
 
void EffectSummonPet (SpellEffIndex effIndex)
 
void EffectLearnPetSpell (SpellEffIndex effIndex)
 
void EffectWeaponDmg (SpellEffIndex effIndex)
 
void EffectForceCast (SpellEffIndex effIndex)
 
void EffectTriggerSpell (SpellEffIndex effIndex)
 
void EffectTriggerMissileSpell (SpellEffIndex effIndex)
 
void EffectThreat (SpellEffIndex effIndex)
 
void EffectHealMaxHealth (SpellEffIndex effIndex)
 
void EffectInterruptCast (SpellEffIndex effIndex)
 
void EffectSummonObjectWild (SpellEffIndex effIndex)
 
void EffectScriptEffect (SpellEffIndex effIndex)
 
void EffectSanctuary (SpellEffIndex effIndex)
 
void EffectAddComboPoints (SpellEffIndex effIndex)
 
void EffectDuel (SpellEffIndex effIndex)
 
void EffectStuck (SpellEffIndex effIndex)
 
void EffectSummonPlayer (SpellEffIndex effIndex)
 
void EffectActivateObject (SpellEffIndex effIndex)
 
void EffectApplyGlyph (SpellEffIndex effIndex)
 
void EffectEnchantHeldItem (SpellEffIndex effIndex)
 
void EffectSummonObject (SpellEffIndex effIndex)
 
void EffectResurrect (SpellEffIndex effIndex)
 
void EffectParry (SpellEffIndex effIndex)
 
void EffectBlock (SpellEffIndex effIndex)
 
void EffectLeap (SpellEffIndex effIndex)
 
void EffectTransmitted (SpellEffIndex effIndex)
 
void EffectDisEnchant (SpellEffIndex effIndex)
 
void EffectInebriate (SpellEffIndex effIndex)
 
void EffectFeedPet (SpellEffIndex effIndex)
 
void EffectDismissPet (SpellEffIndex effIndex)
 
void EffectReputation (SpellEffIndex effIndex)
 
void EffectForceDeselect (SpellEffIndex effIndex)
 
void EffectSelfResurrect (SpellEffIndex effIndex)
 
void EffectSkinning (SpellEffIndex effIndex)
 
void EffectCharge (SpellEffIndex effIndex)
 
void EffectChargeDest (SpellEffIndex effIndex)
 
void EffectProspecting (SpellEffIndex effIndex)
 
void EffectMilling (SpellEffIndex effIndex)
 
void EffectRenamePet (SpellEffIndex effIndex)
 
void EffectSendTaxi (SpellEffIndex effIndex)
 
void EffectSummonCritter (SpellEffIndex effIndex)
 
void EffectKnockBack (SpellEffIndex effIndex)
 
void EffectPullTowards (SpellEffIndex effIndex)
 
void EffectDispelMechanic (SpellEffIndex effIndex)
 
void EffectResurrectPet (SpellEffIndex effIndex)
 
void EffectDestroyAllTotems (SpellEffIndex effIndex)
 
void EffectDurabilityDamage (SpellEffIndex effIndex)
 
void EffectSkill (SpellEffIndex effIndex)
 
void EffectTaunt (SpellEffIndex effIndex)
 
void EffectDurabilityDamagePCT (SpellEffIndex effIndex)
 
void EffectModifyThreatPercent (SpellEffIndex effIndex)
 
void EffectResurrectNew (SpellEffIndex effIndex)
 
void EffectAddExtraAttacks (SpellEffIndex effIndex)
 
void EffectSpiritHeal (SpellEffIndex effIndex)
 
void EffectSkinPlayerCorpse (SpellEffIndex effIndex)
 
void EffectStealBeneficialBuff (SpellEffIndex effIndex)
 
void EffectUnlearnSpecialization (SpellEffIndex effIndex)
 
void EffectHealPct (SpellEffIndex effIndex)
 
void EffectEnergizePct (SpellEffIndex effIndex)
 
void EffectTriggerRitualOfSummoning (SpellEffIndex effIndex)
 
void EffectSummonRaFFriend (SpellEffIndex effIndex)
 
void EffectKillCreditPersonal (SpellEffIndex effIndex)
 
void EffectKillCredit (SpellEffIndex effIndex)
 
void EffectQuestFail (SpellEffIndex effIndex)
 
void EffectQuestStart (SpellEffIndex effIndex)
 
void EffectRedirectThreat (SpellEffIndex effIndex)
 
void EffectGameObjectDamage (SpellEffIndex effIndex)
 
void EffectGameObjectRepair (SpellEffIndex effIndex)
 
void EffectGameObjectSetDestructionState (SpellEffIndex effIndex)
 
void EffectActivateRune (SpellEffIndex effIndex)
 
void EffectCreateTamedPet (SpellEffIndex effIndex)
 
void EffectDiscoverTaxi (SpellEffIndex effIndex)
 
void EffectTitanGrip (SpellEffIndex effIndex)
 
void EffectEnchantItemPrismatic (SpellEffIndex effIndex)
 
void EffectPlayMusic (SpellEffIndex effIndex)
 
void EffectSpecCount (SpellEffIndex effIndex)
 
void EffectActivateSpec (SpellEffIndex effIndex)
 
void EffectPlaySound (SpellEffIndex effIndex)
 
void EffectRemoveAura (SpellEffIndex effIndex)
 
void EffectCastButtons (SpellEffIndex effIndex)
 
void EffectRechargeManaGem (SpellEffIndex effIndex)
 
void InitExplicitTargets (SpellCastTargets const &targets)
 
void SelectExplicitTargets ()
 
void SelectSpellTargets ()
 
void SelectEffectImplicitTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
 
void SelectImplicitChannelTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitNearbyTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitConeTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitAreaTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitCasterDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitDestDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitCasterObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitChainTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
 
void SelectImplicitTrajTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectEffectTypeImplicitTargets (uint8 effIndex)
 
uint32 GetSearcherTypeMask (SpellTargetObjectTypes objType, ConditionList *condList)
 
template<class SEARCHER >
void SearchTargets (SEARCHER &searcher, uint32 containerMask, Unit *referer, Position const *pos, float radius)
 
WorldObjectSearchNearbyTarget (float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
 
void SearchAreaTargets (std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
 
void SearchChainTargets (std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
 
SpellCastResult prepare (SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
 
void cancel (bool bySelf=false)
 
void update (uint32 difftime)
 
void cast (bool skipCheck=false)
 
void _cast (bool skipCheck)
 
void finish (bool ok=true)
 
void TakePower ()
 
void TakeAmmo ()
 
void TakeRunePower (bool didHit)
 
void TakeReagents ()
 
void TakeCastItem ()
 
SpellCastResult CheckCast (bool strict)
 
SpellCastResult CheckPetCast (Unit *target)
 
void handle_immediate ()
 
uint64 handle_delayed (uint64 t_offset)
 
void _handle_immediate_phase ()
 
void _handle_finish_phase ()
 
void OnSpellLaunch ()
 
SpellCastResult CheckItems ()
 
SpellCastResult CheckSpellFocus ()
 
SpellCastResult CheckRange (bool strict)
 
SpellCastResult CheckPower ()
 
SpellCastResult CheckRuneCost (uint32 RuneCostID)
 
SpellCastResult CheckCasterAuras (bool preventionOnly) const
 
int32 CalculateSpellDamage (uint8 i, Unit const *target) const
 
bool HaveTargetsForEffect (uint8 effect) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint8 effIndex, uint32 itemId)
 
void WriteSpellGoTargets (WorldPacket *data)
 Writes miss and hit targets for a SMSG_SPELL_GO packet. More...
 
void WriteAmmoToPacket (WorldPacket *data)
 
bool CheckEffectTarget (Unit const *target, uint32 eff) const
 
bool CanAutoCast (Unit *target)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result)
 
void SendPetCastResult (SpellCastResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendLogExecute ()
 
void ExecuteLogEffectTakeTargetPower (uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
 
void ExecuteLogEffectExtraAttacks (uint8 effIndex, Unit *victim, uint32 attCount)
 
void ExecuteLogEffectInterruptCast (uint8 effIndex, Unit *victim, uint32 spellId)
 
void ExecuteLogEffectDurabilityDamage (uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
 
void ExecuteLogEffectOpenLock (uint8 effIndex, Object *obj)
 
void ExecuteLogEffectCreateItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectDestroyItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectSummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectUnsummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectResurrect (uint8 effIndex, Unit *target)
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
 
void HandleThreatSpells ()
 
void AddComboPointGain (Unit *target, int8 amount)
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsTriggered () const
 
bool HasTriggeredCastFlag (TriggerCastFlags flag) const
 
bool IsChannelActive () const
 
bool IsAutoActionResetSpell () const
 
bool IsIgnoringCooldowns () const
 
bool IsDeletable () const
 
void SetReferencedFromCurrent (bool yes)
 
bool IsInterruptable () const
 
void SetExecutedCurrently (bool yes)
 
uint64 GetDelayStart () const
 
void SetDelayStart (uint64 m_time)
 
uint64 GetDelayMoment () const
 
uint64 GetDelayTrajectory () const
 
uint64 CalculateDelayMomentForDst () const
 
void RecalculateDelayMomentForDst ()
 
bool IsNeedSendToClient (bool go) const
 
CurrentSpellTypes GetCurrentContainer () const
 
UnitGetCaster () const
 
UnitGetOriginalCaster () const
 
SpellInfo const * GetSpellInfo () const
 
int32 GetPowerCost () const
 
bool UpdatePointers ()
 
void CleanupTargetList ()
 
void SetSpellValue (SpellValueMod mod, int32 value)
 
SpellValue const * GetSpellValue ()
 
void LoadScripts ()
 
std::list< TargetInfo > * GetUniqueTargetInfo ()
 
uint32 GetTriggeredByAuraTickNumber () const
 
TriggerCastFlags GetTriggeredCastFlags () const
 
SpellSchoolMask GetSpellSchoolMask () const
 

Static Public Member Functions

static void WriteCastResultInfo (WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
 
static void SendCastResult (Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
 

Public Attributes

SpellInfo const *const m_spellInfo
 
Itemm_CastItem
 
Itemm_weaponItem
 
ObjectGuid m_castItemGUID
 
uint8 m_cast_count
 
uint32 m_glyphIndex
 
uint32 m_preCastSpell
 
SpellCastTargets m_targets
 
SpellCustomErrors m_customError
 
Unitm_comboTarget
 
int8 m_comboPointGain
 
UsedSpellMods m_appliedMods
 

Protected Types

typedef std::list< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

bool HasGlobalCooldown () const
 
void TriggerGlobalCooldown ()
 
void CancelGlobalCooldown ()
 
void SendLoot (ObjectGuid guid, LootType loottype)
 
std::string GetDebugInfo () const
 
bool isDelayableNoMore ()
 
void prepareDataForTriggerSystem (AuraEffect const *triggeredByAura)
 
void AddUnitTarget (Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
 
void AddGOTarget (GameObject *target, uint32 effectMask)
 
void AddItemTarget (Item *item, uint32 effectMask)
 
void AddDestTarget (SpellDestination const &dest, uint32 effIndex)
 
void DoAllEffectOnTarget (TargetInfo *target)
 
SpellMissInfo DoSpellHitOnUnit (Unit *unit, uint32 effectMask, bool scaleAura)
 
void DoTriggersOnSpellHit (Unit *unit, uint8 effMask)
 
void DoAllEffectOnTarget (GOTargetInfo *target)
 
void DoAllEffectOnTarget (ItemTargetInfo *target)
 
bool UpdateChanneledTargetList ()
 
bool IsValidDeadOrAliveTarget (Unit const *target) const
 
void HandleLaunchPhase ()
 
void DoAllEffectOnLaunchTarget (TargetInfo &targetInfo, float *multiplier)
 
void PrepareTargetProcessing ()
 
void FinishTargetProcessing ()
 
void InitEffectExecuteData (uint8 effIndex)
 
void CheckEffectExecuteData ()
 
void CallScriptBeforeCastHandlers ()
 
void CallScriptOnCastHandlers ()
 
void CallScriptAfterCastHandlers ()
 
SpellCastResult CallScriptCheckCastHandlers ()
 
void PrepareScriptHitHandlers ()
 
bool CallScriptEffectHandlers (SpellEffIndex effIndex, SpellEffectHandleMode mode)
 
void CallScriptBeforeHitHandlers (SpellMissInfo missInfo)
 
void CallScriptOnHitHandlers ()
 
void CallScriptAfterHitHandlers ()
 
void CallScriptObjectAreaTargetSelectHandlers (std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptObjectTargetSelectHandlers (WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptDestinationTargetSelectHandlers (SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
bool CheckScriptEffectImplicitTargets (uint32 effIndex, uint32 effIndexToCheck)
 
bool CanExecuteTriggersOnHit (uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
 
void PrepareTriggersExecutedOnHit ()
 
void SummonGuardian (uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
 
void CalculateJumpSpeeds (uint8 i, float dist, float &speedxy, float &speedz)
 
SpellCastResult CanOpenLock (uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
 

Protected Attributes

Unit *const m_caster
 
SpellValue *const m_spellValue
 
ObjectGuid m_originalCasterGUID
 
Unitm_originalCaster
 
Spell ** m_selfContainer
 
SpellSchoolMask m_spellSchoolMask
 
WeaponAttackType m_attackType
 
int32 m_powerCost
 
int32 m_casttime
 
int32 m_channeledDuration
 
bool m_canReflect
 
uint8 m_spellFlags
 
bool m_autoRepeat
 
uint8 m_runesState
 
uint8 m_delayAtDamageCount
 
uint64 m_delayStart
 
uint64 m_delayMoment
 
uint64 m_delayTrajectory
 
bool m_immediateHandled
 
bool m_referencedFromCurrentSpell
 
bool m_executedCurrently
 
bool m_needComboPoints
 
uint8 m_applyMultiplierMask
 
float m_damageMultipliers [3]
 
UnitunitTarget
 
ItemitemTarget
 
GameObjectgameObjTarget
 
WorldLocationdestTarget
 
int32 damage
 
SpellEffectHandleMode effectHandleMode
 
Auram_spellAura
 
DiminishingLevels m_diminishLevel
 
DiminishingGroup m_diminishGroup
 
GameObjectfocusObject
 
int32 m_damage
 
int32 m_healing
 
uint32 m_procAttacker
 
uint32 m_procVictim
 
uint32 m_procEx
 
std::list< TargetInfom_UniqueTargetInfo
 
uint8 m_channelTargetEffectMask
 
std::list< GOTargetInfom_UniqueGOTargetInfo
 
std::list< ItemTargetInfom_UniqueItemInfo
 
SpellDestination m_destTargets [MAX_SPELL_EFFECTS]
 
bool _scriptsLoaded
 
std::list< SpellScript * > m_loadedScripts
 
HitTriggerSpellList m_hitTriggerSpells
 
uint32 m_spellState
 
int32 m_timer
 
SpellEvent_spellEvent
 
TriggerCastFlags _triggeredCastFlags
 
TriggeredByAuraSpellData m_triggeredByAuraSpell
 
bool m_skipCheck
 
uint8 m_auraScaleMask
 
std::unique_ptr< PathGeneratorm_preGeneratedPath
 
bool _spellTargetsSelected
 
ByteBufferm_effectExecuteData [MAX_SPELL_EFFECTS]
 

Friends

class SpellScript
 
void Unit::SetCurrentCastedSpell (Spell *pSpell)
 

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

typedef std::list<HitTriggerSpell> Spell::HitTriggerSpellList
protected

◆ UsedSpellMods

typedef std::set<Aura*> Spell::UsedSpellMods

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
568 :
569 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
570 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
572{
574 m_skipCheck = skipCheck;
575 m_selfContainer = nullptr;
577 m_executedCurrently = false;
580 m_comboTarget = nullptr;
581 m_delayStart = 0;
583
585 m_auraScaleMask = 0;
586 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
587
588 // Get data for type of attack
589 switch (m_spellInfo->DmgClass)
590 {
594 else
596 break;
599 break;
600 default:
601 // Wands
604 else
606 break;
607 }
608
609 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
610
612 // wand case
615 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
616
617 if (originalCasterGUID)
618 m_originalCasterGUID = originalCasterGUID;
619 else
621
624 else
625 {
628 m_originalCaster = nullptr;
629 }
630
632 _triggeredCastFlags = triggerFlags;
633 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
635
636 m_CastItem = nullptr;
637
638 unitTarget = nullptr;
639 itemTarget = nullptr;
640 gameObjTarget = nullptr;
641 destTarget = nullptr;
642 damage = 0;
646 m_damage = 0;
647 m_healing = 0;
648 m_procAttacker = 0;
649 m_procVictim = 0;
650 m_procEx = 0;
651 focusObject = nullptr;
652 m_cast_count = 0;
653 m_glyphIndex = 0;
654 m_preCastSpell = 0;
655 m_spellAura = nullptr;
656 _scriptsLoaded = false;
657
658 //Auto Shot & Shoot (wand)
660
661 m_runesState = 0;
662 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
663 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
664 m_timer = 0; // will set to castime in prepare
665 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
666 m_immediateHandled = false;
667
669
671
672 // Determine if spell can be reflected back to the caster
673 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
677
679 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
680
681 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
683
684 // xinef:
685 _spellTargetsSelected = false;
686
687 m_weaponItem = nullptr;
688}
std::uint8_t uint8
Definition: Define.h:109
std::uint32_t uint32
Definition: Define.h:107
@ OFF_ATTACK
Definition: Unit.h:210
@ BASE_ATTACK
Definition: Unit.h:209
@ RANGED_ATTACK
Definition: Unit.h:211
@ DIMINISHING_LEVEL_1
Definition: Unit.h:263
TriggerCastFlags
Definition: SpellDefines.h:130
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition: SpellDefines.h:139
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition: SpellDefines.h:137
#define sSpellMgr
Definition: SpellMgr.h:825
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition: Spell.h:233
@ SPELL_FLAG_NORMAL
Definition: Spell.h:81
@ SPELL_STATE_NULL
Definition: Spell.h:223
@ DIMINISHING_NONE
Definition: SharedDefines.h:3258
@ SPELL_EFFECT_DISPEL
Definition: SharedDefines.h:816
#define CLASSMASK_WAND_USERS
Definition: SharedDefines.h:174
@ SPELL_ATTR2_AUTO_REPEAT
Definition: SharedDefines.h:461
@ SPELL_ATTR1_NO_REFLECTION
Definition: SharedDefines.h:426
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition: SharedDefines.h:517
@ SPELL_DAMAGE_CLASS_RANGED
Definition: SharedDefines.h:1548
@ SPELL_DAMAGE_CLASS_MAGIC
Definition: SharedDefines.h:1546
@ SPELL_DAMAGE_CLASS_MELEE
Definition: SharedDefines.h:1547
@ SPELL_CUSTOM_ERROR_NONE
Definition: SharedDefines.h:1143
@ SPELL_ATTR0_IS_ABILITY
Definition: SharedDefines.h:386
@ SPELL_ATTR0_NO_IMMUNITIES
Definition: SharedDefines.h:411
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition: SharedDefines.h:537
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition: SharedDefines.h:622
SpellSchoolMask
Definition: SharedDefines.h:295
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1636
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:202
Definition: Item.h:220
bool IsPlayer() const
Definition: Object.h:197
Player * ToPlayer()
Definition: Object.h:198
bool IsInWorld() const
Definition: Object.h:104
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:109
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: PlayerStorage.cpp:490
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1255
uint32 getClassMask() const
Definition: Unit.h:749
Definition: Spell.h:94
Definition: Spell.h:211
Unit * m_comboTarget
Definition: Spell.h:542
int8 m_comboPointGain
Definition: Spell.h:543
GameObject * gameObjTarget
Definition: Spell.h:653
bool m_referencedFromCurrentSpell
Definition: Spell.h:644
bool m_canReflect
Definition: Spell.h:620
uint32 m_procVictim
Definition: Spell.h:675
Unit * m_originalCaster
Definition: Spell.h:608
bool m_needComboPoints
Definition: Spell.h:646
uint64 m_delayStart
Definition: Spell.h:638
bool _scriptsLoaded
Definition: Spell.h:726
TriggerCastFlags _triggeredCastFlags
Definition: Spell.h:767
int32 damage
Definition: Spell.h:655
SpellEffectHandleMode effectHandleMode
Definition: Spell.h:656
int32 m_channeledDuration
Definition: Spell.h:619
Aura * m_spellAura
Definition: Spell.h:658
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition: Spell.h:701
Unit *const m_caster
Definition: Spell.h:602
uint8 m_delayAtDamageCount
Definition: Spell.h:627
WeaponAttackType m_attackType
Definition: Spell.h:616
bool m_immediateHandled
Definition: Spell.h:641
uint32 m_spellState
Definition: Spell.h:763
ObjectGuid m_originalCasterGUID
Definition: Spell.h:606
void CleanupTargetList()
Definition: Spell.cpp:2372
int32 m_timer
Definition: Spell.h:764
int32 m_casttime
Definition: Spell.h:618
Item * itemTarget
Definition: Spell.h:652
uint8 m_cast_count
Definition: Spell.h:524
int32 m_damage
Definition: Spell.h:668
bool m_executedCurrently
Definition: Spell.h:645
DiminishingLevels m_diminishLevel
Definition: Spell.h:661
float m_damageMultipliers[3]
Definition: Spell.h:648
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition: Spell.h:781
uint8 m_auraScaleMask
Definition: Spell.h:775
SpellCustomErrors m_customError
Definition: Spell.h:528
uint8 m_spellFlags
Definition: Spell.h:622
bool m_skipCheck
Definition: Spell.h:774
int32 m_healing
Definition: Spell.h:669
uint32 m_glyphIndex
Definition: Spell.h:525
uint8 m_channelTargetEffectMask
Definition: Spell.h:683
Item * m_weaponItem
Definition: Spell.h:522
Unit * unitTarget
Definition: Spell.h:651
SpellSchoolMask m_spellSchoolMask
Definition: Spell.h:615
SpellEvent * _spellEvent
Definition: Spell.h:766
bool _spellTargetsSelected
Definition: Spell.h:779
uint32 m_preCastSpell
Definition: Spell.h:526
WorldLocation * destTarget
Definition: Spell.h:654
Spell ** m_selfContainer
Definition: Spell.h:610
uint8 m_applyMultiplierMask
Definition: Spell.h:647
DiminishingGroup m_diminishGroup
Definition: Spell.h:662
uint32 m_procEx
Definition: Spell.h:676
Item * m_CastItem
Definition: Spell.h:521
SpellValue *const m_spellValue
Definition: Spell.h:604
int32 m_powerCost
Definition: Spell.h:617
uint32 m_procAttacker
Definition: Spell.h:674
GameObject * focusObject
Definition: Spell.h:665
SpellInfo const *const m_spellInfo
Definition: Spell.h:520
uint8 m_runesState
Definition: Spell.h:625
bool m_autoRepeat
Definition: Spell.h:624
bool IsPassive() const
Definition: SpellInfo.cpp:1097
bool NeedsComboPoints() const
Definition: SpellInfo.cpp:1265
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:415
bool HasEffect(SpellEffects effect) const
Definition: SpellInfo.cpp:875
bool IsPositive() const
Definition: SpellInfo.cpp:1236
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1282
uint32 DmgClass
Definition: SpellInfo.h:389
bool IsRangedWeaponSpell() const
Definition: SpellInfo.cpp:1275
Definition: ByteBuffer.h:70

References _scriptsLoaded, _spellTargetsSelected, _triggeredCastFlags, BASE_ATTACK, CLASSMASK_WAND_USERS, CleanupTargetList(), damage, destTarget, DIMINISHING_LEVEL_1, DIMINISHING_NONE, SpellInfo::DmgClass, effectHandleMode, focusObject, gameObjTarget, Unit::getClassMask(), Object::GetGUID(), SpellInfo::GetSchoolMask(), ObjectAccessor::GetUnit(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsInWorld(), SpellInfo::IsPassive(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsRangedWeaponSpell(), itemTarget, m_applyMultiplierMask, m_attackType, m_auraScaleMask, m_autoRepeat, m_canReflect, m_cast_count, m_caster, m_CastItem, m_casttime, m_channeledDuration, m_channelTargetEffectMask, m_comboPointGain, m_comboTarget, m_customError, m_damage, m_damageMultipliers, m_delayAtDamageCount, m_delayStart, m_destTargets, m_diminishGroup, m_diminishLevel, m_effectExecuteData, m_executedCurrently, m_glyphIndex, m_healing, m_immediateHandled, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_powerCost, m_preCastSpell, m_procAttacker, m_procEx, m_procVictim, m_referencedFromCurrentSpell, m_runesState, m_selfContainer, m_skipCheck, m_spellAura, m_spellFlags, m_spellInfo, m_spellSchoolMask, m_spellState, m_timer, m_weaponItem, MAX_SPELL_EFFECTS, SpellInfo::NeedsComboPoints(), OFF_ATTACK, RANGED_ATTACK, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_CUSTOM_ERROR_NONE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_FLAG_NORMAL, SPELL_STATE_NULL, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and unitTarget.

◆ ~Spell()

Spell::~Spell ( )
691{
692 // unload scripts
693 while (!m_loadedScripts.empty())
694 {
695 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
696 (*itr)->_Unload();
697 delete (*itr);
698 m_loadedScripts.erase(itr);
699 }
700
702 {
703 // Clean the reference to avoid later crash.
704 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
705 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
706 *m_selfContainer = nullptr;
707 }
708
709 delete m_spellValue;
710
712}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:156
void CheckEffectExecuteData()
Definition: Spell.cpp:8489
std::list< SpellScript * > m_loadedScripts
Definition: Spell.h:741
uint32 Id
Definition: SpellInfo.h:320

References CheckEffectExecuteData(), SpellInfo::Id, LOG_ERROR, m_loadedScripts, m_referencedFromCurrentSpell, m_selfContainer, m_spellInfo, and m_spellValue.

Member Function Documentation

◆ _cast()

void Spell::_cast ( bool  skipCheck)

Not own traded item (in trader trade slot) req. reagents including triggered spell case

3808{
3809 // update pointers base at GUIDs to prevent access to non-existed already object
3810 if (!UpdatePointers())
3811 {
3812 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3813 cancel();
3814 return;
3815 }
3816
3817 // cancel at lost explicit target during cast
3819 {
3820 cancel();
3821 return;
3822 }
3823
3824 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3826 {
3828 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3830
3831 if (Unit* charm = m_caster->GetCharm())
3832 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3833 }
3834
3835 if (Player* playerCaster = m_caster->ToPlayer())
3836 {
3837 // now that we've done the basic check, now run the scripts
3838 // should be done before the spell is actually executed
3839 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3840
3841 // As of 3.0.2 pets begin attacking their owner's target immediately
3842 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3843 // This prevents spells such as Hunter's Mark from triggering pet attack
3844 // xinef: take into account SPELL_ATTR3_SUPRESS_TARGET_PROCS
3846 if (!playerCaster->m_Controlled.empty())
3847 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3848 if (Unit* pet = *itr)
3849 if (pet->IsAlive() && pet->IsCreature())
3850 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3851 }
3852
3854
3858
3860
3861 Player* modOwner = m_caster->GetSpellModOwner();
3862 // skip check if done already (for instant cast spells for example)
3863 if (!skipCheck)
3864 {
3865 SpellCastResult castResult = CheckCast(false);
3866 if (castResult != SPELL_CAST_OK)
3867 {
3868 SendCastResult(castResult);
3869 SendInterrupted(0);
3870
3871 finish(false);
3872 SetExecutedCurrently(false);
3873 return;
3874 }
3875
3876 // additional check after cast bar completes (must not be in CheckCast)
3877 // if trade not complete then remember it in trade data
3879 {
3880 if (m_caster->IsPlayer())
3881 {
3882 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3883 {
3884 if (!my_trade->IsInAcceptProcess())
3885 {
3886 // Spell will be casted at completing the trade. Silently ignore at this place
3887 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3889 SendInterrupted(0);
3890
3891 finish(false);
3892 SetExecutedCurrently(false);
3893 return;
3894 }
3895 }
3896 }
3897 }
3898 }
3899
3900 if (modOwner)
3901 modOwner->SetSpellModTakingSpell(this, true);
3902
3905
3906 if (modOwner)
3907 modOwner->SetSpellModTakingSpell(this, false);
3908
3909 // Spell may be finished after target map check
3911 {
3912 SendInterrupted(0);
3913 finish(false);
3914 SetExecutedCurrently(false);
3915 return;
3916 }
3917
3918 if (modOwner)
3919 modOwner->SetSpellModTakingSpell(this, true);
3920
3922
3924
3925 if (modOwner)
3926 modOwner->SetSpellModTakingSpell(this, false);
3927
3928 // traded items have trade slot instead of guid in m_itemTargetGUID
3929 // set to real guid to be sent later to the client
3931
3932 if (m_caster->IsPlayer())
3933 {
3935 {
3938 }
3939
3941 }
3942
3944 {
3945 // Powers have to be taken before SendSpellGo
3946 TakePower();
3947 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3948 }
3949 else if (Item* targetItem = m_targets.GetItemTarget())
3950 {
3952 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3953 TakeReagents();
3954 }
3955
3957
3958 // CAST SPELL
3959 if (modOwner)
3960 modOwner->SetSpellModTakingSpell(this, true);
3961
3963
3965
3966 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3967 SendSpellGo();
3968
3969 if (modOwner)
3970 modOwner->SetSpellModTakingSpell(this, false);
3971
3972 if (m_originalCaster)
3973 {
3974 // Handle procs on cast
3975 uint32 procAttacker = m_procAttacker;
3976 if (!procAttacker)
3977 {
3978 bool IsPositive = m_spellInfo->IsPositive();
3980 {
3982 }
3983 else
3984 {
3986 }
3987 }
3988
3989 uint32 procEx = PROC_EX_NORMAL_HIT;
3990
3991 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3992 {
3993 if (ihit->missCondition != SPELL_MISS_NONE)
3994 {
3995 continue;
3996 }
3997
3998 if (!ihit->crit)
3999 {
4000 continue;
4001 }
4002
4003 procEx |= PROC_EX_CRITICAL_HIT;
4004 break;
4005 }
4006
4009 }
4010
4011 if (modOwner)
4012 modOwner->SetSpellModTakingSpell(this, true);
4013
4015 if (resetAttackTimers)
4016 {
4018 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
4019 {
4020 if ((*i)->IsAffectedOnSpell(m_spellInfo))
4021 {
4022 resetAttackTimers = false;
4023 break;
4024 }
4025 }
4026 }
4027
4028 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4029 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4030 {
4031 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4032 // in case delayed spell remove item at cast delay start
4033 TakeCastItem();
4034
4035 // Okay, maps created, now prepare flags
4036 m_immediateHandled = false;
4038 SetDelayStart(0);
4039
4042
4043 // remove all applied mods at this point
4044 // dont allow user to use them twice in case spell did not reach current target
4045 if (modOwner)
4046 modOwner->RemoveSpellMods(this);
4047
4048 // Xinef: why do we keep focus after spell is sent to air?
4049 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4050 // Xinef: we get focused to it out of nowhere...
4051 if (Creature* creatureCaster = m_caster->ToCreature())
4052 creatureCaster->ReleaseFocus(this);
4053 }
4054 else
4055 {
4056 // Immediate spell, no big deal
4058 }
4059
4060 if (resetAttackTimers)
4061 {
4062 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4063 {
4064 resetAttackTimers = false;
4065 }
4066
4067 if (resetAttackTimers)
4068 {
4070
4072 {
4074 }
4075
4077 }
4078 }
4079
4081
4082 if (modOwner)
4083 modOwner->SetSpellModTakingSpell(this, false);
4084
4085 if (const std::vector<int32>* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4086 {
4087 for (std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
4088 if (*i < 0)
4090 else
4092 }
4093
4094 // Interrupt Spell casting
4095 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4097 if (Unit* target = m_targets.GetUnitTarget())
4098 if (target->IsCreature())
4099 m_caster->CastSpell(target, 32747, true);
4100
4101 // xinef: start combat at cast for delayed spells, only for explicit target
4102 if (Unit* target = m_targets.GetUnitTarget())
4105 m_caster->CombatStartOnCast(target, !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPRESS_TARGET_PROCS), GetDelayMoment() + 500); // xinef: increase this time so we dont leave and enter combat in a moment
4106
4107 if (m_caster->IsPlayer())
4110
4111 SetExecutedCurrently(false);
4112}
#define sScriptMgr
Definition: ScriptMgr.h:708
@ UNIT_STATE_CASTING
Definition: UnitDefines.h:164
@ CHEAT_COOLDOWN
Definition: Player.h:1001
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:42
@ SPELL_AURA_MOD_CHARM
Definition: SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition: SpellAuraDefines.h:335
@ SPELL_AURA_BIND_SIGHT
Definition: SpellAuraDefines.h:64
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition: SpellDefines.h:134
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition: SpellDefines.h:135
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition: SpellDefines.h:141
@ PROC_EX_CRITICAL_HIT
Definition: SpellMgr.h:195
@ PROC_EX_NORMAL_HIT
Definition: SpellMgr.h:194
@ PROC_SPELL_PHASE_CAST
Definition: SpellMgr.h:243
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:128
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:122
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:125
@ PROC_FLAG_NONE
Definition: SpellMgr.h:105
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:131
@ TARGET_FLAG_TRADE_ITEM
Definition: SpellInfo.h:58
@ TARGET_FLAG_UNIT
Definition: SpellInfo.h:47
@ SPELL_STATE_DELAYED
Definition: Spell.h:228
@ SPELL_STATE_FINISHED
Definition: Spell.h:226
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition: SharedDefines.h:652
@ SPELL_EFFECT_SUMMON_PET
Definition: SharedDefines.h:834
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition: SharedDefines.h:473
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition: SharedDefines.h:419
@ SPELL_ATTR3_SUPRESS_TARGET_PROCS
Definition: SharedDefines.h:510
@ SPELL_DAMAGE_CLASS_NONE
Definition: SharedDefines.h:1545
@ SPELL_MISS_NONE
Definition: SharedDefines.h:1519
SpellCastResult
Definition: SharedDefines.h:948
@ SPELL_FAILED_DONT_REPORT
Definition: SharedDefines.h:976
@ SPELL_CAST_OK
Definition: SharedDefines.h:1138
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition: DBCEnums.h:115
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition: DBCEnums.h:155
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition: DBCEnums.h:143
Definition: Creature.h:46
uint32 GetEntry() const
Definition: Object.h:112
bool IsCreature() const
Definition: Object.h:201
Creature * ToCreature()
Definition: Object.h:202
Definition: Pet.h:41
Definition: Player.h:1064
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition: PlayerUpdates.cpp:2127
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition: Player.cpp:10077
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition: Player.cpp:13923
void RemoveSpellMods(Spell *spell)
Definition: Player.cpp:10009
Pet * GetPet() const
Definition: Player.cpp:8906
bool GetCommandStatus(uint32 command) const
Definition: Player.h:1178
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:9057
TradeData * GetTradeData() const
Definition: Player.h:1370
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition: Player.cpp:3503
Definition: TradeData.h:36
Definition: Unit.h:630
bool HasOffhandWeaponForAttack() const
Definition: Unit.h:1064
void ClearUnitState(uint32 f)
Definition: Unit.h:674
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1374
Unit * GetCharm() const
Definition: Unit.cpp:10627
Player * GetSpellModOwner() const
Definition: Unit.cpp:16532
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition: Unit.cpp:13661
bool IsPet() const
Definition: Unit.h:710
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:4080
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1167
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4890
static void ProcDamageAndSpell(Unit *actor, Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=BASE_ATTACK, SpellInfo const *procSpellInfo=nullptr, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
Definition: Unit.cpp:6348
bool HasUnitState(const uint32 f) const
Definition: Unit.h:673
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:10202
bool IsControlledByPlayer() const
Definition: Unit.h:1236
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:646
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:20486
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition: Unit.cpp:642
WorldObject * GetObjectTarget() const
Definition: Spell.cpp:312
void UpdateTradeSlotItem()
Definition: Spell.cpp:349
ObjectGuid GetObjectTargetGUID() const
Definition: Spell.cpp:317
Item * GetItemTarget() const
Definition: Spell.h:139
uint32 GetTargetMask() const
Definition: Spell.h:117
Unit * GetUnitTarget() const
Definition: Spell.cpp:233
int8 effectIndex
Definition: Spell.h:279
SpellInfo const * spellInfo
Definition: Spell.h:278
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:575
void CallScriptAfterCastHandlers()
Definition: Spell.cpp:8543
void PrepareTriggersExecutedOnHit()
Definition: Spell.cpp:8749
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition: Spell.h:553
SpellCastTargets m_targets
Definition: Spell.h:527
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition: Spell.h:772
void handle_immediate()
Definition: Spell.cpp:4114
void SendSpellGo()
Definition: Spell.cpp:4796
void TakeReagents()
Definition: Spell.cpp:5530
void SetExecutedCurrently(bool yes)
Definition: Spell.h:561
void SendInterrupted(uint8 result)
Definition: Spell.cpp:5173
void PrepareScriptHitHandlers()
Definition: Spell.cpp:8575
void CallScriptOnCastHandlers()
Definition: Spell.cpp:8530
void cancel(bool bySelf=false)
Definition: Spell.cpp:3719
void SendSpellCooldown()
Definition: Spell.cpp:4354
void CallScriptBeforeCastHandlers()
Definition: Spell.cpp:8517
void HandleLaunchPhase()
Definition: Spell.cpp:8230
bool UpdatePointers()
Definition: Spell.cpp:7860
void SetDelayStart(uint64 m_time)
Definition: Spell.h:563
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:682
void SelectSpellTargets()
Definition: Spell.cpp:816
void TakePower()
Definition: Spell.cpp:5314
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:5652
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition: Spell.cpp:4668
uint64 GetDelayMoment() const
Definition: Spell.h:564
void TakeCastItem()
Definition: Spell.cpp:5251
bool IsAutoActionResetSpell() const
Definition: Spell.cpp:8074
void finish(bool ok=true)
Definition: Spell.cpp:4481
float Speed
Definition: SpellInfo.h:370
bool IsChanneled() const
Definition: SpellInfo.cpp:1255
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2351
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:892

References _spellTargetsSelected, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_TIMED_TYPE_ITEM, BASE_ATTACK, SpellInfo::CalcCastTime(), CallScriptAfterCastHandlers(), CallScriptBeforeCastHandlers(), CallScriptOnCastHandlers(), cancel(), Unit::CastSpell(), CHEAT_COOLDOWN, CheckCast(), Unit::ClearUnitState(), Unit::CombatStartOnCast(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, finish(), Unit::GetAuraEffectsByType(), Unit::GetCharm(), Player::GetCommandStatus(), GetDelayMoment(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetObjectTargetGUID(), Player::GetPet(), GetSpellInfo(), Unit::GetSpellModOwner(), SpellCastTargets::GetTargetMask(), Player::GetTradeData(), SpellCastTargets::GetUnitTarget(), handle_immediate(), HandleLaunchPhase(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::HasEffect(), Unit::HasOffhandWeaponForAttack(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, IsAutoActionResetSpell(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsNonMeleeSpellCast(), Unit::IsPet(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_CastItem, m_casttime, m_immediateHandled, m_originalCaster, m_procAttacker, m_spellInfo, m_spellState, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, OFF_ATTACK, PET_SAVE_AS_CURRENT, PrepareScriptHitHandlers(), PrepareTriggersExecutedOnHit(), PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_CAST, Unit::ProcDamageAndSpell(), RANGED_ATTACK, Unit::RemoveAurasDueToSpell(), Player::RemovePet(), Player::RemoveSpellCooldown(), Player::RemoveSpellMods(), Unit::resetAttackTimer(), SelectSpellTargets(), SendCastResult(), SendInterrupted(), SendSpellCooldown(), SendSpellGo(), SetDelayStart(), SetExecutedCurrently(), Unit::SetInFront(), Player::SetSpellModTakingSpell(), SpellInfo::Speed, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_AURA_BIND_SIGHT, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_MOD_CHARM, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_SUMMON_PET, SPELL_FAILED_DONT_REPORT, SPELL_MISS_NONE, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, TriggeredByAuraSpellData::spellInfo, sScriptMgr, sSpellMgr, Player::StartTimedAchievement(), TakeCastItem(), TakePower(), TakeReagents(), TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_IGNORE_CAST_ITEM, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SET_FACING, UNIT_STATE_CASTING, Player::UpdateAchievementCriteria(), UpdatePointers(), and SpellCastTargets::UpdateTradeSlotItem().

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4280{
4281 // Take for real after all targets are processed
4283 {
4285 }
4286
4287 // Real add combo points from effects
4289 {
4290 // remove Premed-like effects unless they were caused by ourselves
4291 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4293 {
4295 }
4296
4298 }
4299
4301 {
4303 }
4304
4307 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4308 {
4309 // Xinef: Properly clear infinite cooldowns in some cases
4310 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4313 }
4314
4315 // Handle procs on finish
4316 if (m_originalCaster)
4317 {
4318 uint32 procAttacker = m_procAttacker;
4319 if (!procAttacker)
4320 {
4321 bool IsPositive = m_spellInfo->IsPositive();
4323 {
4325 }
4326 else
4327 {
4329 }
4330 }
4331
4332 uint32 procEx = PROC_EX_NORMAL_HIT;
4333 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4334 {
4335 if (ihit->missCondition != SPELL_MISS_NONE)
4336 {
4337 continue;
4338 }
4339
4340 if (!ihit->crit)
4341 {
4342 continue;
4343 }
4344
4345 procEx |= PROC_EX_CRITICAL_HIT;
4346 break;
4347 }
4348
4351 }
4352}
@ SPELL_AURA_RETAIN_COMBO_POINTS
Definition: SpellAuraDefines.h:211
@ PROC_SPELL_PHASE_FINISH
Definition: SpellMgr.h:245
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition: SharedDefines.h:797
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition: Player.cpp:11105
void SetLastExtraAttackSpell(uint32 spellId)
Definition: Unit.h:1017
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:10577
void ClearComboPoints()
Definition: Unit.cpp:16819
void AddComboPoints(Unit *target, int8 count)
Definition: Unit.cpp:16793
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition: Unit.cpp:5080
bool IsAutoRepeat() const
Definition: Spell.h:548
bool IsNextMeleeSwingSpell() const
Definition: Spell.cpp:8064
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1211

References Unit::AddComboPoints(), BASE_ATTACK, Unit::ClearComboPoints(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetGUID(), SpellInfo::HasAura(), SpellInfo::HasEffect(), SpellInfo::Id, IsAutoRepeat(), SpellInfo::IsCooldownStartedOnEvent(), IsNextMeleeSwingSpell(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_comboPointGain, m_comboTarget, m_needComboPoints, m_originalCaster, m_procAttacker, m_spellInfo, m_triggeredByAuraSpell, m_UniqueTargetInfo, PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_FINISH, Unit::ProcDamageAndSpell(), Unit::RemoveAurasByType(), Player::SendCooldownEvent(), Unit::SetLastExtraAttackSpell(), SPELL_AURA_RETAIN_COMBO_POINTS, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_ADD_EXTRA_ATTACKS, SPELL_MISS_NONE, TriggeredByAuraSpellData::spellInfo, and Object::ToPlayer().

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4252{
4253 m_spellAura = nullptr;
4254 // initialize Diminishing Returns Data
4257
4258 // handle some immediate features of the spell here
4260
4262
4263 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4264 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4265 {
4266 // don't do anything for empty effect
4267 if (!m_spellInfo->Effects[j].IsEffect())
4268 continue;
4269
4270 // call effect handlers to handle destination hit
4271 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4272 }
4273
4274 // process items
4275 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4276 DoAllEffectOnTarget(&(*ihit));
4277}
@ SPELL_EFFECT_HANDLE_HIT
Definition: Spell.h:235
void HandleThreatSpells()
Definition: Spell.cpp:5579
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition: Spell.cpp:5626
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:699
void DoAllEffectOnTarget(TargetInfo *target)
Definition: Spell.cpp:2610
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:393

References DIMINISHING_LEVEL_1, DIMINISHING_NONE, DoAllEffectOnTarget(), SpellInfo::Effects, HandleEffects(), HandleThreatSpells(), m_diminishGroup, m_diminishLevel, m_spellAura, m_spellInfo, m_UniqueItemInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), and SPELL_EFFECT_HANDLE_HIT.

Referenced by handle_delayed(), and handle_immediate().

◆ AddComboPointGain()

void Spell::AddComboPointGain ( Unit target,
int8  amount 
)
inline
531 {
532 if (target != m_comboTarget)
533 {
534 m_comboTarget = target;
535 m_comboPointGain = amount;
536 }
537 else
538 {
539 m_comboPointGain += amount;
540 }
541 }

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2606{
2607 m_destTargets[effIndex] = dest;
2608}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2515{
2516 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2517 {
2518 if (!m_spellInfo->Effects[effIndex].IsEffect())
2519 effectMask &= ~(1 << effIndex);
2520 else
2521 {
2522 switch (m_spellInfo->Effects[effIndex].Effect)
2523 {
2527 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2528 effectMask &= ~(1 << effIndex);
2529 break;
2530 default:
2531 break;
2532 }
2533 }
2534 }
2535
2536 if (!effectMask)
2537 return;
2538
2539 ObjectGuid targetGUID = go->GetGUID();
2540
2541 // Lookup target in already in list
2542 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2543 {
2544 if (targetGUID == ihit->targetGUID) // Found in list
2545 {
2546 ihit->effectMask |= effectMask; // Add only effect mask
2547 return;
2548 }
2549 }
2550
2551 // This is new target calculate data for him
2552
2553 GOTargetInfo target;
2554 target.targetGUID = targetGUID;
2555 target.effectMask = effectMask;
2556 target.processed = false; // Effects not apply on target
2557
2558 // Spell have speed - need calculate incoming time
2559 if (m_spellInfo->Speed > 0.0f)
2560 {
2561 // calculate spell incoming interval
2562 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2563 if (dist < 5.0f)
2564 dist = 5.0f;
2565 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2566 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2567 m_delayMoment = target.timeDelay;
2568 }
2569 else
2570 target.timeDelay = 0LL;
2571
2572 // Add target to list
2573 m_UniqueGOTargetInfo.push_back(target);
2574}
std::uint64_t uint64
Definition: Define.h:106
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition: SharedDefines.h:1593
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition: SharedDefines.h:866
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition: SharedDefines.h:867
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition: SharedDefines.h:865
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1245
Definition: ObjectGuid.h:118
uint64 m_delayMoment
Definition: Spell.h:639
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition: Spell.h:692

References Spell::GOTargetInfo::effectMask, SpellInfo::Effects, GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING, WorldObject::GetDistance(), GameObject::GetGoType(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), m_caster, m_delayMoment, m_spellInfo, m_UniqueGOTargetInfo, MAX_SPELL_EFFECTS, Spell::GOTargetInfo::processed, SpellInfo::Speed, SPELL_EFFECT_GAMEOBJECT_DAMAGE, SPELL_EFFECT_GAMEOBJECT_REPAIR, SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE, Spell::GOTargetInfo::targetGUID, and Spell::GOTargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ AddItemTarget()

void Spell::AddItemTarget ( Item item,
uint32  effectMask 
)
protected
2577{
2578 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2579 if (!m_spellInfo->Effects[effIndex].IsEffect())
2580 effectMask &= ~(1 << effIndex);
2581
2582 // no effects left
2583 if (!effectMask)
2584 return;
2585
2586 // Lookup target in already in list
2587 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2588 {
2589 if (item == ihit->item) // Found in list
2590 {
2591 ihit->effectMask |= effectMask; // Add only effect mask
2592 return;
2593 }
2594 }
2595
2596 // This is new target add data
2597
2598 ItemTargetInfo target;
2599 target.item = item;
2600 target.effectMask = effectMask;
2601
2602 m_UniqueItemInfo.push_back(target);
2603}

References Spell::ItemTargetInfo::effectMask, SpellInfo::Effects, Spell::ItemTargetInfo::item, m_spellInfo, m_UniqueItemInfo, and MAX_SPELL_EFFECTS.

Referenced by SelectEffectTypeImplicitTargets(), and SelectImplicitTargetObjectTargets().

◆ AddUnitTarget()

void Spell::AddUnitTarget ( Unit target,
uint32  effectMask,
bool  checkIfValid = true,
bool  implicit = true 
)
protected
Todo:
: this is a hack
Todo:
: seduction should be casted only on humanoids (not demons)
2382{
2383 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2384 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2385 effectMask &= ~(1 << effIndex);
2386
2387 // no effects left
2388 if (!effectMask)
2389 return;
2390
2391 if (checkIfValid)
2392 {
2393 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2394 if (res != SPELL_CAST_OK)
2395 return;
2396 }
2397
2398 // Check for effect immune skip if immuned
2399 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2400 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
2401 effectMask &= ~(1 << effIndex);
2402
2403 ObjectGuid targetGUID = target->GetGUID();
2404
2405 // Lookup target in already in list
2406 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2407 {
2408 if (targetGUID == ihit->targetGUID) // Found in list
2409 {
2410 ihit->effectMask |= effectMask; // Immune effects removed from mask
2411 ihit->scaleAura = false;
2412 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2413 {
2414 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2415 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2416 ihit->scaleAura = true;
2417 }
2418
2419 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2420 return;
2421 }
2422 }
2423
2424 // This is new target calculate data for him
2425
2426 // Get spell hit result on target
2427 TargetInfo targetInfo;
2428 targetInfo.targetGUID = targetGUID; // Store target GUID
2429 targetInfo.effectMask = effectMask; // Store all effects not immune
2430 targetInfo.processed = false; // Effects not apply on target
2431 targetInfo.alive = target->IsAlive();
2432 targetInfo.damage = 0;
2433 targetInfo.crit = false;
2434 targetInfo.scaleAura = false;
2435 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2436 {
2437 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2438 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2439 targetInfo.scaleAura = true;
2440 }
2441
2442 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2443
2444 // Calculate hit result
2445 if (m_originalCaster)
2446 {
2447 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2448 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2449 {
2450 targetInfo.missCondition = SPELL_MISS_NONE;
2451 }
2452 }
2453 else
2454 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2455
2456 // Spell have speed - need calculate incoming time
2457 // Incoming time is zero for self casts. At least I think so.
2458 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2459 {
2460 // calculate spell incoming interval
2462 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2463
2464 if (dist < 5.0f)
2465 dist = 5.0f;
2466 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2467
2468 // Calculate minimum incoming time
2469 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2470 m_delayMoment = targetInfo.timeDelay;
2471 }
2472 else
2473 targetInfo.timeDelay = 0LL;
2474
2475 // If target reflect spell back to caster
2476 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2477 {
2478 // Calculate reflected spell result on caster
2480
2481 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2482 targetInfo.reflectResult = SPELL_MISS_PARRY;
2483
2484 // Increase time interval for reflected spells by 1.5
2486 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2487
2489
2490 // HACK: workaround check for succubus seduction case
2492 if (m_caster->IsPet())
2493 {
2494 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2495 switch (ci->family)
2496 {
2498 {
2499 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2500 cancel();
2501 }
2502 break;
2503 return;
2504 }
2505 }
2506 }
2507 else
2508 targetInfo.reflectResult = SPELL_MISS_NONE;
2509
2510 // Add target to list
2511 m_UniqueTargetInfo.push_back(targetInfo);
2512}
#define sObjectMgr
Definition: ObjectMgr.h:1623
@ SPELL_FLAG_REFLECTED
Definition: Spell.h:82
@ CREATURE_FAMILY_SUCCUBUS
Definition: SharedDefines.h:2664
@ SPELL_MISS_PARRY
Definition: SharedDefines.h:1523
@ SPELL_MISS_IMMUNE
Definition: SharedDefines.h:1526
@ SPELL_MISS_EVADE
Definition: SharedDefines.h:1525
@ SPELL_MISS_REFLECT
Definition: SharedDefines.h:1530
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
Definition: EventProcessor.h:103
uint64 CalculateTime(uint64 t_offset) const
Definition: EventProcessor.cpp:159
Definition: CreatureData.h:187
uint32 family
Definition: CreatureData.h:218
float GetPositionZ() const
Definition: Position.h:119
float GetPositionX() const
Definition: Position.h:117
float GetPositionY() const
Definition: Position.h:118
bool IsAlive() const
Definition: Unit.h:1216
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition: Unit.cpp:3453
EventProcessor m_Events
Definition: Unit.h:1809
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition: Unit.cpp:12962
uint8 GetLevel() const
Definition: Unit.h:855
Definition: Spell.h:254
bool processed
Definition: Spell.h:260
int32 damage
Definition: Spell.h:264
SpellMissInfo missCondition
Definition: Spell.h:257
bool scaleAura
Definition: Spell.h:263
bool crit
Definition: Spell.h:262
uint64 timeDelay
Definition: Spell.h:256
ObjectGuid targetGUID
Definition: Spell.h:255
SpellMissInfo reflectResult
Definition: Spell.h:258
bool alive
Definition: Spell.h:261
uint8 effectMask
Definition: Spell.h:259
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition: Spell.cpp:7922
Definition: Spell.h:846
Definition: SpellInfo.h:316
uint32 SpellLevel
Definition: SpellInfo.h:360
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:2500
uint32 SpellIconID
Definition: SpellInfo.h:380
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
Definition: SpellInfo.cpp:1758

References EventProcessor::AddEvent(), TargetInfo::alive, EventProcessor::CalculateTime(), cancel(), CheckEffectTarget(), SpellInfo::CheckTarget(), CREATURE_FAMILY_SUCCUBUS, TargetInfo::crit, TargetInfo::damage, TargetInfo::effectMask, SpellInfo::Effects, CreatureTemplate::family, WorldObject::GetDistance(), Object::GetEntry(), SpellInfo::GetFirstRankSpell(), Object::GetGUID(), Unit::GetLevel(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Unit::IsImmunedToSpellEffect(), Unit::IsPet(), m_auraScaleMask, m_canReflect, m_caster, m_delayMoment, Unit::m_Events, m_originalCaster, m_skipCheck, m_spellFlags, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::processed, TargetInfo::reflectResult, TargetInfo::scaleAura, sObjectMgr, SpellInfo::Speed, SPELL_CAST_OK, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, Unit::SpellHitResult(), SpellInfo::SpellIconID, SpellInfo::SpellLevel, sScriptMgr, TargetInfo::targetGUID, and TargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CalculateDelayMomentForDst()

uint64 Spell::CalculateDelayMomentForDst ( ) const
897{
898 if (m_targets.HasDst())
899 {
900 if (m_targets.HasTraj())
901 {
902 float speed = m_targets.GetSpeedXY();
903 if (speed > 0.0f)
904 return (uint64)std::floor(m_targets.GetDist2d() / speed * 1000.0f);
905 }
906 else if (m_spellInfo->Speed > 0.0f)
907 {
908 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
909 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
910 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
911 }
912 }
913
914 return 0;
915}
float GetExactDist(float x, float y, float z) const
Definition: Position.h:178
bool HasTraj() const
Definition: Spell.h:166
bool HasDst() const
Definition: Spell.h:165
float GetSpeedXY() const
Definition: Spell.h:174
float GetDist2d() const
Definition: Spell.h:173
WorldLocation const * GetDstPos() const
Definition: Spell.cpp:402

References SpellCastTargets::GetDist2d(), SpellCastTargets::GetDstPos(), Position::GetExactDist(), SpellCastTargets::GetSpeedXY(), SpellCastTargets::HasDst(), SpellCastTargets::HasTraj(), m_caster, m_spellInfo, m_targets, and SpellInfo::Speed.

Referenced by RecalculateDelayMomentForDst(), and SelectSpellTargets().

◆ CalculateJumpSpeeds()

void Spell::CalculateJumpSpeeds ( uint8  i,
float  dist,
float &  speedxy,
float &  speedz 
)
protected
1158{
1159 if (m_spellInfo->Effects[i].MiscValue)
1160 speedZ = float(m_spellInfo->Effects[i].MiscValue) / 10;
1161 else if (m_spellInfo->Effects[i].MiscValueB)
1162 speedZ = float(m_spellInfo->Effects[i].MiscValueB) / 10;
1163 else
1164 speedZ = 10.0f;
1165 speedXY = dist * 10.0f / speedZ;
1166}

References SpellInfo::Effects, and m_spellInfo.

Referenced by EffectJump(), and EffectJumpDest().

◆ CalculateSpellDamage()

int32 Spell::CalculateSpellDamage ( uint8  i,
Unit const *  target 
) const
inline
int32 CalculateSpellDamage(Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=nullptr) const
Definition: Unit.cpp:14805
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition: Spell.h:213

References Unit::CalculateSpellDamage(), SpellValue::EffectBasePoints, m_caster, m_spellInfo, and m_spellValue.

Referenced by CheckCast(), CheckEffectTarget(), EffectWeaponDmg(), and HandleEffects().

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8544{
8545 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8546 {
8547 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8548 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8549 for (; hookItr != hookItrEnd; ++hookItr)
8550 (*hookItr).Call(*scritr);
8551
8552 (*scritr)->_FinishScriptCall();
8553 }
8554}
@ SPELL_SCRIPT_HOOK_AFTER_CAST
Definition: SpellScript.h:172

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_CAST.

Referenced by _cast().

◆ CallScriptAfterHitHandlers()

void Spell::CallScriptAfterHitHandlers ( )
protected
8656{
8657 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8658 {
8659 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8660 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8661 for (; hookItr != hookItrEnd; ++hookItr)
8662 (*hookItr).Call(*scritr);
8663
8664 (*scritr)->_FinishScriptCall();
8665 }
8666}
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition: SpellScript.h:165

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8518{
8519 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8520 {
8521 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8522 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8523 for (; hookItr != hookItrEnd; ++hookItr)
8524 (*hookItr).Call(*scritr);
8525
8526 (*scritr)->_FinishScriptCall();
8527 }
8528}
@ SPELL_SCRIPT_HOOK_BEFORE_CAST
Definition: SpellScript.h:170

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_CAST.

Referenced by _cast().

◆ CallScriptBeforeHitHandlers()

void Spell::CallScriptBeforeHitHandlers ( SpellMissInfo  missInfo)
protected
8630{
8631 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8632 {
8633 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8634 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8635 for (; hookItr != hookItrEnd; ++hookItr)
8636 (*hookItr).Call(*scritr, missInfo);
8637
8638 (*scritr)->_FinishScriptCall();
8639 }
8640}
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition: SpellScript.h:163

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8557{
8559 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8560 {
8561 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8562 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8563 for (; hookItr != hookItrEnd; ++hookItr)
8564 {
8565 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8566 if (retVal == SPELL_CAST_OK)
8567 retVal = tempResult;
8568 }
8569
8570 (*scritr)->_FinishScriptCall();
8571 }
8572 return retVal;
8573}
@ SPELL_SCRIPT_HOOK_CHECK_CAST
Definition: SpellScript.h:169

References m_loadedScripts, SPELL_CAST_OK, and SPELL_SCRIPT_HOOK_CHECK_CAST.

Referenced by CheckCast().

◆ CallScriptDestinationTargetSelectHandlers()

void Spell::CallScriptDestinationTargetSelectHandlers ( SpellDestination target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8697{
8698 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8699 {
8700 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8701 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8702 for (; hookItr != hookItrEnd; ++hookItr)
8703 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8704 hookItr->Call(*scritr, target);
8705
8706 (*scritr)->_FinishScriptCall();
8707 }
8708}
@ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT
Definition: SpellScript.h:168

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT.

Referenced by SelectImplicitCasterDestTargets(), SelectImplicitDestDestTargets(), SelectImplicitTargetDestTargets(), and SelectImplicitTrajTargets().

◆ CallScriptEffectHandlers()

bool Spell::CallScriptEffectHandlers ( SpellEffIndex  effIndex,
SpellEffectHandleMode  mode 
)
protected
8582{
8583 // execute script effect handler hooks and check if effects was prevented
8584 bool preventDefault = false;
8585 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8586 {
8587 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8588 SpellScriptHookType hookType;
8589 switch (mode)
8590 {
8592 effItr = (*scritr)->OnEffectLaunch.begin();
8593 effEndItr = (*scritr)->OnEffectLaunch.end();
8595 break;
8597 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8598 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8600 break;
8602 effItr = (*scritr)->OnEffectHit.begin();
8603 effEndItr = (*scritr)->OnEffectHit.end();
8605 break;
8607 effItr = (*scritr)->OnEffectHitTarget.begin();
8608 effEndItr = (*scritr)->OnEffectHitTarget.end();
8610 break;
8611 default:
8612 ABORT();
8613 return false;
8614 }
8615 (*scritr)->_PrepareScriptCall(hookType);
8616 for (; effItr != effEndItr; ++effItr)
8617 // effect execution can be prevented
8618 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8619 (*effItr).Call(*scritr, effIndex);
8620
8621 if (!preventDefault)
8622 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8623
8624 (*scritr)->_FinishScriptCall();
8625 }
8626 return preventDefault;
8627}
#define ABORT
Definition: Errors.h:76
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition: Spell.h:234
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition: Spell.h:236
SpellScriptHookType
Definition: SpellScript.h:158
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
Definition: SpellScript.h:161
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
Definition: SpellScript.h:159
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
Definition: SpellScript.h:160
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
Definition: SpellScript.h:162

References ABORT, m_loadedScripts, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCRIPT_HOOK_EFFECT_HIT, SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET, SPELL_SCRIPT_HOOK_EFFECT_LAUNCH, and SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET.

Referenced by HandleEffects().

◆ CallScriptObjectAreaTargetSelectHandlers()

void Spell::CallScriptObjectAreaTargetSelectHandlers ( std::list< WorldObject * > &  targets,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8669{
8670 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8671 {
8672 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8673 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8674 for (; hookItr != hookItrEnd; ++hookItr)
8675 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8676 hookItr->Call(*scritr, targets);
8677
8678 (*scritr)->_FinishScriptCall();
8679 }
8680}
@ SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT
Definition: SpellScript.h:166

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT.

Referenced by SelectImplicitAreaTargets(), SelectImplicitChainTargets(), and SelectImplicitConeTargets().

◆ CallScriptObjectTargetSelectHandlers()

void Spell::CallScriptObjectTargetSelectHandlers ( WorldObject *&  target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8683{
8684 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8685 {
8686 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8687 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8688 for (; hookItr != hookItrEnd; ++hookItr)
8689 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8690 hookItr->Call(*scritr, target);
8691
8692 (*scritr)->_FinishScriptCall();
8693 }
8694}
@ SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT
Definition: SpellScript.h:167

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CallScriptOnCastHandlers()

void Spell::CallScriptOnCastHandlers ( )
protected
8531{
8532 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8533 {
8534 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8535 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8536 for (; hookItr != hookItrEnd; ++hookItr)
8537 (*hookItr).Call(*scritr);
8538
8539 (*scritr)->_FinishScriptCall();
8540 }
8541}
@ SPELL_SCRIPT_HOOK_ON_CAST
Definition: SpellScript.h:171

References m_loadedScripts, and SPELL_SCRIPT_HOOK_ON_CAST.

Referenced by _cast().

◆ CallScriptOnHitHandlers()

void Spell::CallScriptOnHitHandlers ( )
protected
8643{
8644 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8645 {
8646 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8647 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8648 for (; hookItr != hookItrEnd; ++hookItr)
8649 (*hookItr).Call(*scritr);
8650
8651 (*scritr)->_FinishScriptCall();
8652 }
8653}
@ SPELL_SCRIPT_HOOK_HIT
Definition: SpellScript.h:164

References m_loadedScripts, and SPELL_SCRIPT_HOOK_HIT.

Referenced by DoAllEffectOnTarget().

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
7007{
7008 ObjectGuid targetguid = target->GetGUID();
7009
7010 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
7011 {
7013 {
7014 if (m_spellInfo->StackAmount <= 1)
7015 {
7016 if (target->HasAuraEffect(m_spellInfo->Id, j))
7017 return false;
7018 }
7019 else
7020 {
7021 if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
7022 if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
7023 return false;
7024 }
7025 }
7026 else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
7027 {
7028 if (target->HasAuraEffect(m_spellInfo->Id, j))
7029 return false;
7030 }
7031 }
7032
7033 SpellCastResult result = CheckPetCast(target);
7034
7035 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7036 {
7038 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7039 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7040 if (ihit->targetGUID == targetguid)
7041 return true;
7042 }
7043 return false; //target invalid
7044}
@ SPELL_EFFECT_APPLY_AURA
Definition: SharedDefines.h:784
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition: SharedDefines.h:1083
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition: Unit.cpp:5464
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition: Unit.cpp:5638
Definition: SpellAuraEffects.h:39
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6813
uint32 StackAmount
Definition: SpellInfo.h:371

References CheckPetCast(), SpellInfo::Effects, Unit::GetAuraEffect(), Object::GetGUID(), Unit::HasAuraEffect(), SpellInfo::Id, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectSpellTargets(), SPELL_CAST_OK, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_UNIT_NOT_INFRONT, and SpellInfo::StackAmount.

Referenced by PetAI::UpdateAI().

◆ cancel()

void Spell::cancel ( bool  bySelf = false)
3720{
3722 return;
3723
3724 uint32 oldState = m_spellState;
3726
3727 m_autoRepeat = false;
3728 switch (oldState)
3729 {
3733
3734 if (m_caster->IsPlayer())
3735 {
3737 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3738 }
3739 [[fallthrough]];
3742 break;
3744 if (!bySelf)
3745 {
3746 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3747 if ((*ihit).missCondition == SPELL_MISS_NONE)
3748 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3749 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3750
3753
3756 }
3757
3759 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3760
3761 // spell is canceled-take mods and clear list
3762 if (Player* player = m_caster->GetSpellModOwner())
3763 player->RemoveSpellMods(this);
3764
3765 m_appliedMods.clear();
3766 break;
3767 default:
3768 break;
3769 }
3770
3772 if (m_selfContainer && *m_selfContainer == this)
3773 *m_selfContainer = nullptr;
3774
3775 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3777 {
3779 }
3780
3781 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3783
3784 //set state back so finish will be processed
3785 m_spellState = oldState;
3786
3787 finish(false);
3788}
@ AURA_REMOVE_BY_CANCEL
Definition: SpellAuraDefines.h:393
@ SPELL_STATE_PREPARING
Definition: Spell.h:224
@ SPELL_STATE_CASTING
Definition: Spell.h:225
@ SPELL_EFFECT_ADD_FARSIGHT
Definition: SharedDefines.h:850
@ SPELL_FAILED_INTERRUPTED
Definition: SharedDefines.h:989
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition: ArenaSpectator.h:80
Map * FindMap() const
Definition: Object.h:532
bool NeedSendSpectatorData() const
Definition: Player.cpp:15405
void RemoveGameObject(GameObject *gameObj, bool del)
Definition: Unit.cpp:6167
bool RemoveDynObject(uint32 spellId)
Definition: Unit.cpp:6111
void SendChannelUpdate(uint32 time)
Definition: Spell.cpp:5190
void CancelGlobalCooldown()
Definition: Spell.cpp:8884
void SetReferencedFromCurrent(bool yes)
Definition: Spell.h:559
UsedSpellMods m_appliedMods
Definition: Spell.h:545

References AURA_REMOVE_BY_CANCEL, CancelGlobalCooldown(), WorldObject::FindMap(), finish(), Object::GetGUID(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasEffect(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsPlayer(), m_appliedMods, m_autoRepeat, m_caster, m_originalCasterGUID, m_selfContainer, m_spellInfo, m_spellState, m_UniqueTargetInfo, Player::NeedSendSpectatorData(), Unit::RemoveDynObject(), Unit::RemoveGameObject(), Player::RemoveSpellCooldown(), SendCastResult(), SendChannelUpdate(), ArenaSpectator::SendCommand_Spell(), SendInterrupted(), SetReferencedFromCurrent(), SPELL_EFFECT_ADD_FARSIGHT, SPELL_FAILED_INTERRUPTED, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, SPELL_STATE_PREPARING, and Object::ToPlayer().

Referenced by _cast(), SpellEvent::Abort(), AddUnitTarget(), SpellScript::Cancel(), Unit::InterruptSpell(), update(), and SpellEvent::~SpellEvent().

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8885{
8887 return;
8888
8889 // Cancel global cooldown when interrupting current cast
8891 return;
8892
8893 // Only players or controlled units have global cooldown
8894 if (m_caster->GetCharmInfo())
8896 else if (m_caster->IsPlayer())
8898}
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:538
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: Player.h:1787
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition: CharmInfo.cpp:415
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: CharmInfo.h:158
CharmInfo * GetCharmInfo()
Definition: Unit.h:1290
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:1468
uint32 StartRecoveryTime
Definition: SpellInfo.h:351

References GlobalCooldownMgr::CancelGlobalCooldown(), CURRENT_GENERIC_SPELL, Unit::GetCharmInfo(), Unit::GetCurrentSpell(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), Object::IsPlayer(), m_caster, m_spellInfo, SpellInfo::StartRecoveryTime, and Object::ToPlayer().

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8734{
8735 // Relentless strikes, proc only from first effect
8736 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8737 return effMask & (1 << EFFECT_0);
8738
8739 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8740 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8741 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8742 {
8743 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8744 return true;
8745 }
8746 return effMask;
8747}
@ EFFECT_0
Definition: SharedDefines.h:31
@ TARGET_UNIT_CASTER
Definition: SharedDefines.h:1410
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition: SharedDefines.h:531

References EFFECT_0, SpellInfo::Effects, SpellInfo::HasAttribute(), m_spellInfo, MAX_SPELL_EFFECTS, SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET, SpellInfo::SpellIconID, and TARGET_UNIT_CASTER.

Referenced by DoAllEffectOnTarget(), and DoTriggersOnSpellHit().

◆ CanOpenLock()

SpellCastResult Spell::CanOpenLock ( uint32  effIndex,
uint32  lockid,
SkillType skillid,
int32 reqSkillValue,
int32 skillValue 
)
protected
8358{
8359 if (!lockId) // possible case for GO and maybe for items.
8360 return SPELL_CAST_OK;
8361
8362 // Get LockInfo
8363 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8364
8365 if (!lockInfo)
8367
8368 bool reqKey = false; // some locks not have reqs
8369
8370 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8371 {
8372 switch (lockInfo->Type[j])
8373 {
8374 // check key item (many fit cases can be)
8375 case LOCK_KEY_ITEM:
8376 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8377 return SPELL_CAST_OK;
8378 reqKey = true;
8379 break;
8380 // check key skill (only single first fit case can be)
8381 case LOCK_KEY_SKILL:
8382 {
8383 reqKey = true;
8384
8385 // wrong locktype, skip
8386 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8387 continue;
8388
8389 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8390
8391 if (skillId != SKILL_NONE)
8392 {
8393 reqSkillValue = lockInfo->Skill[j];
8394
8395 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8396 skillValue = m_CastItem || !m_caster->IsPlayer() ?
8397 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8398
8399 // skill bonus provided by casting spell (mostly item spells)
8400 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8401 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8403 {
8404 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8405 }
8406
8407 if (skillValue < reqSkillValue)
8409 }
8410
8411 return SPELL_CAST_OK;
8412 }
8413 case LOCK_KEY_SPELL:
8414 {
8415 if (m_spellInfo->Id == lockInfo->Index[j])
8416 {
8417 return SPELL_CAST_OK;
8418 }
8419 reqKey = true;
8420 break;
8421 }
8422 }
8423 }
8424
8425 if (reqKey)
8427
8428 return SPELL_CAST_OK;
8429}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition: SharedDefines.h:1430
LockType
Definition: SharedDefines.h:2591
@ LOCK_KEY_ITEM
Definition: SharedDefines.h:2585
@ LOCK_KEY_SKILL
Definition: SharedDefines.h:2586
@ LOCK_KEY_SPELL
Definition: SharedDefines.h:2587
@ SPELL_FAILED_BAD_TARGETS
Definition: SharedDefines.h:961
@ SPELL_FAILED_LOW_CASTLEVEL
Definition: SharedDefines.h:998
SkillType SkillByLockType(LockType locktype)
Definition: SharedDefines.h:3020
@ SKILL_NONE
Definition: SharedDefines.h:2864
@ SKILL_LOCKPICKING
Definition: SharedDefines.h:2975
#define MAX_LOCK_CASE
Definition: DBCStructure.h:1304
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5437
bool IsAbilityOfSkillType(uint32 skillType) const
Definition: SpellInfo.cpp:1004
Definition: DBCStructure.h:1307
uint32 Type[MAX_LOCK_CASE]
Definition: DBCStructure.h:1309
uint32 Index[MAX_LOCK_CASE]
Definition: DBCStructure.h:1310
uint32 Skill[MAX_LOCK_CASE]
Definition: DBCStructure.h:1311

References SpellInfo::Effects, Object::GetEntry(), Player::GetSkillValue(), SpellInfo::Id, LockEntry::Index, SpellInfo::IsAbilityOfSkillType(), Object::IsPlayer(), LOCK_KEY_ITEM, LOCK_KEY_SKILL, LOCK_KEY_SPELL, m_caster, m_CastItem, m_spellInfo, MAX_LOCK_CASE, LockEntry::Skill, SKILL_LOCKPICKING, SKILL_NONE, SkillByLockType(), sLockStore, SPELL_CAST_OK, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_LOW_CASTLEVEL, TARGET_GAMEOBJECT_ITEM_TARGET, Object::ToPlayer(), and LockEntry::Type.

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3791{
3792 Player* modOwner = m_caster->GetSpellModOwner();
3793 Spell* lastMod = nullptr;
3794 if (modOwner)
3795 {
3796 lastMod = modOwner->m_spellModTakingSpell;
3797 if (lastMod)
3798 modOwner->SetSpellModTakingSpell(lastMod, false);
3799 }
3800
3801 _cast(skipCheck);
3802
3803 if (lastMod)
3804 modOwner->SetSpellModTakingSpell(lastMod, true);
3805}
Spell * m_spellModTakingSpell
Definition: Player.h:2534
Definition: Spell.h:284
void _cast(bool skipCheck)
Definition: Spell.cpp:3807

References _cast(), Unit::GetSpellModOwner(), m_caster, Player::m_spellModTakingSpell, and Player::SetSpellModTakingSpell().

Referenced by Unit::AttackerStateUpdate(), prepare(), and update().

◆ CheckCast()

SpellCastResult Spell::CheckCast ( bool  strict)
Todo:
: determine if there is some flag to enable/disable the check
5653{
5654 // check death state
5657
5658 // Spectator check
5659 if (m_caster->IsPlayer())
5660 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5661 return SPELL_FAILED_NOT_HERE;
5662
5664
5665 sScriptMgr->OnSpellCheckCast(this, strict, res);
5666
5667 if (res != SPELL_CAST_OK)
5668 return res;
5669
5670 // check cooldowns to prevent cheating
5672 {
5673 if (m_caster->IsPlayer())
5674 {
5675 //can cast triggered (by aura only?) spells while have this flag
5678
5680 {
5683 else
5685 }
5686
5687 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5690 }
5693 }
5694
5696 {
5699 }
5700
5701 // Check global cooldown
5704
5705 // only triggered spells can be processed an ended battleground
5706 if (!IsTriggered() && m_caster->IsPlayer())
5708 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5710
5711 if (m_caster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5712 {
5714 !m_caster->IsOutdoors())
5716
5720 }
5721
5722 // only check at first call, Stealth auras are already removed at second call
5723 // for now, ignore triggered spells
5725 {
5726 bool checkForm = true;
5727 // Ignore form req aura
5729 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5730 {
5731 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5732 continue;
5733 checkForm = false;
5734 break;
5735 }
5736 if (checkForm)
5737 {
5738 // Cannot be used in this stance/form
5740 if (shapeError != SPELL_CAST_OK)
5741 return shapeError;
5742
5745 }
5746 }
5747
5749 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5750 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5752
5753 bool reqCombat = true;
5755 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5756 {
5757 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5758 {
5759 m_needComboPoints = false;
5760 if ((*j)->GetMiscValue() == 1)
5761 {
5762 reqCombat = false;
5763 break;
5764 }
5765 }
5766 }
5767
5768 // caster state requirements
5769 // not for triggered spells (needed by execute)
5771 {
5776
5777 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5782
5783 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5785 }
5786
5787 // Xinef: exploit protection
5789 {
5790 if (m_caster->IsPlayer() && m_caster->GetMap()->IsDungeon())
5791 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5792 if (instanceScript->IsEncounterInProgress())
5793 {
5794 if (Group* group = m_caster->ToPlayer()->GetGroup())
5795 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5796 if (Player* member = itr->GetSource())
5797 if (member->IsInMap(m_caster))
5798 if (Unit* victim = member->GetVictim())
5799 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5800 {
5801 m_caster->CombatStart(victim);
5802 victim->AddThreat(m_caster, 1.0f);
5803 break;
5804 }
5806 }
5807 }
5808
5809 // cancel autorepeat spells if cast start when moving
5810 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5811 if (m_caster->IsPlayer() && m_caster->ToPlayer()->isMoving() && !IsTriggered())
5812 {
5813 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5816 return SPELL_FAILED_MOVING;
5817 }
5818
5819 Vehicle* vehicle = m_caster->GetVehicle();
5821 {
5822 uint16 checkMask = 0;
5823 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5824 {
5825 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5827 {
5828 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5829 if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag
5830 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5831 break;
5832 }
5833 }
5834
5837
5838 if (!checkMask)
5839 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5840
5841 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5842 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5844 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->IsPlayer())
5846 }
5847
5848 // check spell cast conditions from database
5849 {
5852 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5853 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5854 {
5855 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5856 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5857 {
5861 }
5862 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5865 }
5866 }
5867
5868 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5869 // those spells may have incorrect target entries or not filled at all (for example 15332)
5870 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5871 // also, such casts shouldn't be sent to client
5872 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5874 {
5875 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5876 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5878 {
5880 if (castResult != SPELL_CAST_OK)
5881 return castResult;
5882 }
5883 }
5884
5885 if (Unit* target = m_targets.GetUnitTarget())
5886 {
5887 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5888 if (castResult != SPELL_CAST_OK)
5889 return castResult;
5890
5891 if (target != m_caster)
5892 {
5893 // Must be behind the target
5894 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5896
5897 // Target must be facing you
5898 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5900
5903 {
5904 bool castedByGameobject = false;
5905 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5907 {
5908 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5909 }
5910 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5911 {
5912 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5913 {
5914 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5915 }
5916 }
5917
5918 if (castedByGameobject)
5919 {
5920 // If spell casted by gameobject then ignore M2 models
5921 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5922 }
5923
5925 {
5927 }
5928 }
5929 }
5930 }
5931
5932 // Check for line of sight for spells with dest
5933 if (m_targets.HasDst())
5934 {
5935 float x, y, z;
5936 m_targets.GetDstPos()->GetPosition(x, y, z);
5937
5940 {
5941 bool castedByGameobject = false;
5942 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5944 {
5945 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5946 }
5947 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5948 {
5949 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5950 {
5951 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5952 }
5953 }
5954
5955 if (castedByGameobject)
5956 {
5957 // If spell casted by gameobject then ignore M2 models
5958 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5959 }
5960
5962 {
5964 }
5965 }
5966 }
5967
5968 // check pet presence
5969 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5970 {
5971 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5972 {
5974 {
5975 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5977 else
5978 return SPELL_FAILED_NO_PET;
5979 }
5980 break;
5981 }
5982 }
5983 // Spell casted only on battleground
5985 if (!m_caster->ToPlayer()->InBattleground())
5987
5988 // do not allow spells to be cast in arenas
5989 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5990 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5993 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5994 if (mapEntry->IsBattleArena())
5996
5997 // zone check
5999 {
6000 uint32 zone, area;
6001 m_caster->GetZoneAndAreaId(zone, area);
6002
6004 m_caster->IsPlayer() ? m_caster->ToPlayer() : nullptr);
6005 if (locRes != SPELL_CAST_OK)
6006 return locRes;
6007 }
6008
6009 // not let players cast spells at mount (and let do it to creatures)
6012 {
6013 if (m_caster->IsInFlight())
6015 else
6017 }
6018
6019 SpellCastResult castResult = SPELL_CAST_OK;
6020
6021 // always (except passive spells) check items (focus object can be required for any type casts)
6022 if (!m_spellInfo->IsPassive())
6023 {
6024 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
6025 castResult = CheckSpellFocus();
6026 if (castResult != SPELL_CAST_OK)
6027 return castResult;
6028
6029 castResult = CheckItems();
6030 if (castResult != SPELL_CAST_OK)
6031 return castResult;
6032 }
6033
6034 // Triggered spells also have range check
6036 castResult = CheckRange(strict);
6037 if (castResult != SPELL_CAST_OK)
6038 return castResult;
6039
6041 {
6042 castResult = CheckPower();
6043 if (castResult != SPELL_CAST_OK)
6044 return castResult;
6045 }
6046
6048 {
6049 return SPELL_CAST_OK;
6050 }
6051
6052 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6054 {
6056 if (castResult != SPELL_CAST_OK)
6057 return castResult;
6058
6059 // xinef: Enraged Regeneration: While this is active, the warrior is blocked from using abilities that trigger being enraged (which would do nothing and waste the cooldowns).
6061 {
6063 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6064 if (itr->type == m_spellInfo->Mechanic)
6066 }
6067 }
6068
6069 // script hook
6070 castResult = CallScriptCheckCastHandlers();
6071 if (castResult != SPELL_CAST_OK)
6072 return castResult;
6073
6074 bool hasDispellableAura = false;
6075 bool hasNonDispelEffect = false;
6076 uint32 dispelMask = 0;
6077 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6078 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6079 {
6081 {
6082 hasDispellableAura = true;
6083 break;
6084 }
6085
6086 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6087 }
6088 else if (m_spellInfo->Effects[i].IsEffect())
6089 {
6090 hasNonDispelEffect = true;
6091 break;
6092 }
6093
6094 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6095 {
6096 if (Unit* target = m_targets.GetUnitTarget())
6097 {
6098 // Xinef: do not allow to cast on hostile targets in sanctuary
6099 if (!m_caster->IsFriendlyTo(target))
6100 {
6101 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6102 {
6103 // Xinef: fix for duels
6104 Player* player = m_caster->ToPlayer();
6105 if (!player || !player->duel || target != player->duel->Opponent)
6107 }
6108 }
6109
6110 DispelChargesList dispelList;
6111 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6112
6113 if (dispelList.empty())
6115 }
6116 }
6117
6118 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6119 {
6120 // for effects of spells that have only one target
6121 switch (m_spellInfo->Effects[i].Effect)
6122 {
6124 {
6125 if (!m_caster->IsPlayer())
6127
6128 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6129 break;
6130
6131 Pet* pet = m_caster->ToPlayer()->GetPet();
6132
6133 if (!pet)
6134 return SPELL_FAILED_NO_PET;
6135
6136 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6137
6138 if (!learn_spellproto)
6140
6141 if (m_spellInfo->SpellLevel > pet->GetLevel())
6142 return SPELL_FAILED_LOWLEVEL;
6143
6144 break;
6145 }
6147 {
6148 // check target only for unit target case
6150 {
6151 if (!m_caster->IsPlayer())
6153
6154 Pet* pet = unitTarget->ToPet();
6155 if (!pet || pet->GetOwner() != m_caster)
6157
6158 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6159
6160 if (!learn_spellproto)
6162
6163 if (m_spellInfo->SpellLevel > pet->GetLevel())
6164 return SPELL_FAILED_LOWLEVEL;
6165 }
6166 break;
6167 }
6169 {
6170 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6171 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6172 if (m_caster->HasAura(gp->SpellId))
6174 break;
6175 }
6177 {
6178 if (!m_caster->IsPlayer())
6180
6181 Item* foodItem = m_targets.GetItemTarget();
6182 if (!foodItem)
6184
6185 Pet* pet = m_caster->ToPlayer()->GetPet();
6186
6187 if (!pet)
6188 return SPELL_FAILED_NO_PET;
6189
6190 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6192
6193 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6195
6196 if (m_caster->IsInCombat() || pet->IsInCombat())
6198
6199 break;
6200 }
6203 {
6204 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6205 if (m_caster->IsPlayer())
6206 if (Unit* target = m_targets.GetUnitTarget())
6207 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6209 break;
6210 }
6212 {
6214 {
6216 }
6217
6219 {
6220 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6221 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6223 }
6225 {
6226 // Exception for Master's Call
6227 if (m_spellInfo->Id != 54216)
6228 {
6229 return SPELL_FAILED_ROOTED;
6230 }
6231 }
6232 if (m_caster->IsPlayer())
6233 if (Unit* target = m_targets.GetUnitTarget())
6234 if (!target->IsAlive())
6236 // Xinef: Pass only explicit unit target spells
6237 // pussywizard:
6239 {
6240 Unit* target = m_targets.GetUnitTarget();
6241 if (!target)
6243
6244 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6245 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6247
6248 float objSize = target->GetCombatReach();
6249 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6250
6251 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6252 m_preGeneratedPath->SetPathLengthLimit(range);
6253
6254 // first try with raycast, if it fails fall back to normal path
6255 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6256 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6257 return SPELL_FAILED_NOPATH;
6258 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6259 return SPELL_FAILED_NOPATH;
6260 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6261 return SPELL_FAILED_NOPATH;
6262
6263 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6264 }
6265 if (Player* player = m_caster->ToPlayer())
6266 player->SetCanTeleport(true);
6267 break;
6268 }
6270 {
6273
6276
6277 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6278 if (!creature->IsCritter() && !creature->loot.isLooted())
6280
6281 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6282
6283 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6284 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6285 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6286 if (ReqValue > skillValue)
6288
6289 break;
6290 }
6292 {
6293 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6294 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6295 break;
6296
6297 if (!m_caster->IsPlayer() // only players can open locks, gather etc.
6298 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6299 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6301
6302 Item* pTempItem = nullptr;
6304 {
6305 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6306 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6307 }
6310
6311 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6312 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6314 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6316
6317 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6318 if (GameObject* go = m_targets.GetGOTarget())
6319 {
6320 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6321 {
6323 }
6324 }
6325 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6327 {
6328 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6329 {
6330 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6332 }
6333 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6336 }
6337
6338 // get the lock entry
6339 uint32 lockId = 0;
6340 if (GameObject* go = m_targets.GetGOTarget())
6341 {
6342 lockId = go->GetGOInfo()->GetLockId();
6343 if (!lockId)
6345 }
6346 else if (Item* itm = m_targets.GetItemTarget())
6347 lockId = itm->GetTemplate()->LockID;
6348
6349 SkillType skillId = SKILL_NONE;
6350 int32 reqSkillValue = 0;
6351 int32 skillValue = 0;
6352
6353 // check lock compatibility
6354 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6355 if (res != SPELL_CAST_OK)
6356 return res;
6357
6358 // chance for fail at lockpicking attempt
6359 // second check prevent fail at rechecks
6360 // herbalism and mining cannot fail as of patch 3.1.0
6361 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6362 {
6363 // chance for failure in orange lockpick
6364 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6365 {
6367 }
6368 }
6369 break;
6370 }
6372 {
6373 Unit* unitCaster = m_caster->ToUnit();
6374 if (!unitCaster)
6375 {
6377 }
6378
6379 Creature* pet = unitCaster->GetGuardianPet();
6380 if (pet)
6381 {
6382 if (pet->IsAlive())
6383 {
6385 }
6386 }
6387 else if (Player* playerCaster = m_caster->ToPlayer())
6388 {
6389 PetStable& petStable = playerCaster->GetOrInitPetStable();
6390 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6391 {
6392 return SPELL_FAILED_NO_PET;
6393 }
6394 }
6395
6396 break;
6397 }
6398 // This is generic summon effect
6400 {
6401 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6402 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6403 break;
6404 switch (SummonProperties->Category)
6405 {
6407 if (m_caster->GetPetGUID())
6409 [[fallthrough]];
6411 if (m_caster->GetCharmGUID())
6413 break;
6414 }
6415 break;
6416 }
6418 {
6420 {
6425 }
6426 break;
6427 }
6429 {
6430 Unit* unitCaster = m_caster->ToUnit();
6431 if (!unitCaster)
6433
6435 {
6436 if (m_caster->GetPetGUID())
6438 if (m_caster->GetCharmGUID())
6440 }
6441
6443 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6444 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6445
6446 Player* playerCaster = unitCaster->ToPlayer();
6447 if (playerCaster && playerCaster->GetPetStable())
6448 {
6449 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6450 if (info.first)
6451 {
6452 if (info.first->Type == HUNTER_PET)
6453 {
6454 if (!info.first->Health)
6455 {
6456 playerCaster->SendTameFailure(PET_TAME_DEAD);
6458 }
6459
6460 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6461 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6462 {
6463 // if problem in exotic pet
6464 if (creatureInfo && creatureInfo->IsTameable(true))
6466 else
6468
6470 }
6471 }
6472 }
6473 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6474 {
6477 }
6478 }
6479 break;
6480 }
6482 {
6483 if (!m_caster->IsPlayer())
6485 if (!m_caster->GetTarget())
6487
6489 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6491
6492 // Xinef: Implement summon pending error
6493 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6495
6496 // check if our map is dungeon
6497 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6498 if (map->IsDungeon())
6499 {
6500 uint32 mapId = m_caster->GetMap()->GetId();
6501 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6502 /*if (map->IsRaid())
6503 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6504 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6505 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6506
6507 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6508 if (!instance)
6510 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6512 }
6513 break;
6514 }
6515 // RETURN HERE
6517 {
6518 if (!m_caster->IsPlayer())
6520
6521 Player* playerCaster = m_caster->ToPlayer();
6522 //
6523 if (!(playerCaster->GetTarget()))
6525
6527
6528 if (!target ||
6529 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6531
6532 // Xinef: Implement summon pending error
6533 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6535
6536 break;
6537 }
6538 case SPELL_EFFECT_LEAP:
6540 {
6541 //Do not allow to cast it before BG starts.
6542 if (m_caster->IsPlayer())
6543 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6544 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6546 break;
6547 }
6549 {
6552
6553 bool found = false;
6555 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6556 {
6557 if (itr->second->GetBase()->IsPassive())
6558 continue;
6559
6560 if (!itr->second->IsPositive())
6561 continue;
6562
6563 found = true;
6564 break;
6565 }
6566
6567 if (!found)
6569
6570 break;
6571 }
6573 {
6575 {
6576 if (m_caster->IsPlayer())
6577 return SPELL_FAILED_ROOTED;
6578 else
6580 }
6581 break;
6582 }
6583 // xinef: do not allow to use leaps while rooted
6584 case SPELL_EFFECT_JUMP:
6586 {
6588 return SPELL_FAILED_ROOTED;
6589 break;
6590 }
6592 if (!sScriptMgr->CanSelectSpecTalent(this))
6594 // can't change during already started arena/battleground
6595 if (m_caster->IsPlayer())
6596 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6597 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6599 break;
6600 default:
6601 break;
6602 }
6603 }
6604
6605 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6606 {
6607 switch (m_spellInfo->Effects[i].ApplyAuraName)
6608 {
6609 case SPELL_AURA_DUMMY:
6610 break;
6612 {
6613 if (!m_caster->IsPlayer())
6614 return SPELL_FAILED_NO_PET;
6615
6616 Pet* pet = m_caster->ToPlayer()->GetPet();
6617 if (!pet)
6618 return SPELL_FAILED_NO_PET;
6619
6620 if (pet->GetCharmerGUID())
6621 return SPELL_FAILED_CHARMED;
6622 break;
6623 }
6627 {
6628 if (m_caster->GetCharmerGUID())
6629 return SPELL_FAILED_CHARMED;
6630
6631 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6633 {
6634 if (m_caster->GetPetGUID())
6636
6637 if (m_caster->GetCharmGUID())
6639 }
6640 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6641 {
6642 if (m_caster->GetCharmGUID())
6644 }
6645
6646 if (Unit* target = m_targets.GetUnitTarget())
6647 {
6648 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6650
6651 if (target->IsMounted())
6653
6654 if (target->GetCharmerGUID())
6655 return SPELL_FAILED_CHARMED;
6656
6657 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6659
6660 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6662
6663 int32 damage = CalculateSpellDamage(i, target);
6664 if (damage && int32(target->GetLevel()) > damage)
6666 }
6667
6668 break;
6669 }
6670 case SPELL_AURA_MOUNTED:
6671 {
6672 // Disallow casting flying mounts in water
6675
6676 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6677 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6678 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6679 if (it)
6680 allowMount = it->AllowMount;
6681 if (m_caster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6683
6686
6687 // xinef: dont allow to cast mounts in specific transforms
6688 if (m_caster->getTransForm())
6689 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6690 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6691 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6693
6694 break;
6695 }
6697 {
6698 if (!m_targets.GetUnitTarget())
6700
6701 // can be casted at non-friendly unit or own pet/charm
6704
6705 break;
6706 }
6707 case SPELL_AURA_FLY:
6709 {
6710 // Xinef: added water check
6711 if (m_caster->IsInWater())
6713
6714 // not allow cast fly spells if not have req. skills (all spells is self target)
6715 // allow always ghost flight spells
6717 {
6718 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6719 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6720 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6721 return SPELL_FAILED_NOT_HERE;
6722 }
6723 break;
6724 }
6726 {
6727 if (m_spellInfo->Effects[i].IsTargetingArea())
6728 break;
6729
6730 if (!m_caster->IsPlayer() || m_CastItem)
6731 break;
6732
6733 if (!m_targets.GetUnitTarget())
6735
6738
6739 break;
6740 }
6741 case SPELL_AURA_HOVER:
6742 {
6744 {
6746 }
6747 break;
6748 }
6750 {
6751 if (m_caster && m_caster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
6752 {
6754 }
6755 break;
6756 }
6757 default:
6758 break;
6759 }
6760 }
6761
6762 // check trade slot case (last, for allow catch any another cast problems)
6764 {
6765 if (m_CastItem)
6767
6768 if (!m_caster->IsPlayer())
6770
6771 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6772
6773 if (!my_trade)
6775
6777 if (slot != TRADE_SLOT_NONTRADED)
6779
6780 if (!IsTriggered())
6781 if (my_trade->GetSpell())
6783 }
6784
6785 // check if caster has at least 1 combo point on target for spells that require combo points
6787 {
6789 {
6791 {
6793 }
6794 }
6795 else
6796 {
6797 if (!m_caster->GetComboPoints())
6798 {
6800 }
6801 }
6802 }
6803
6804 // xinef: check relic cooldown
6808
6809 // all ok
6810 return SPELL_CAST_OK;
6811}
constexpr auto IN_MILLISECONDS
Definition: Common.h:53
constexpr auto MINUTE
Definition: Common.h:47
int32 irand(int32 min, int32 max)
Definition: Random.cpp:37
std::int32_t int32
Definition: Define.h:103
std::uint16_t uint16
Definition: Define.h:108
#define sConditionMgr
Definition: ConditionMgr.h:289
@ CONDITION_SOURCE_TYPE_SPELL
Definition: ConditionMgr.h:139
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:236
@ STATUS_WAIT_LEAVE
Definition: Battleground.h:203
@ STATUS_IN_PROGRESS
Definition: Battleground.h:202
LineOfSightChecks
Definition: Map.h:191
@ LINEOFSIGHT_ALL_CHECKS
Definition: Map.h:198
#define sBattlefieldMgr
Definition: BattlefieldMgr.h:77
@ PATHFIND_NOPATH
Definition: PathGenerator.h:51
@ PATHFIND_SHORT
Definition: PathGenerator.h:53
@ PATHFIND_INCOMPLETE
Definition: PathGenerator.h:50
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
#define SPECTATOR_SPELL_BINDSIGHT
Definition: ArenaSpectator.h:38
#define WORLD_TRIGGER
Definition: Unit.h:37
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition: Unit.h:77
@ MOVEMENTFLAG_FALLING_FAR
Definition: UnitDefines.h:357
@ CLASS_CONTEXT_PET
Definition: UnitDefines.h:215
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition: UnitDefines.h:285
@ UNIT_STATE_ROOT
Definition: UnitDefines.h:159
@ UNIT_STATE_CHARGING
Definition: UnitDefines.h:166
@ UNIT_FLAG_SKINNABLE
Definition: UnitDefines.h:255
TradeSlots
Definition: TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition: TradeData.h:31
@ PLAYER_ALLOW_ONLY_ABILITY
Definition: Player.h:497
@ GO_STATE_READY
Definition: GameObjectData.h:690
@ INVTYPE_RELIC
Definition: ItemTemplate.h:284
@ HUNTER_PET
Definition: PetDefines.h:32
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition: SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition: SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition: SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition: SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition: SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition: SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition: SpellAuraDefines.h:67
@ SPELL_AURA_FLY
Definition: SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition: SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition: SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition: SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition: SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition: SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition: SpellAuraDefines.h:360
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition: SpellDefines.h:62
@ AURA_INTERRUPT_FLAG_MOUNT
Definition: SpellDefines.h:61
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition: SpellDefines.h:133
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition: SpellDefines.h:143
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition: SpellDefines.h:144
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition: SpellDefines.h:142
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition: SpellDefines.h:132
@ TRIGGERED_IGNORE_EFFECTS
Periodic aura tick wont be reset on override.
Definition: SpellDefines.h:151
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition: SpellDefines.h:145
std::vector< SpellImmune > SpellImmuneList
Definition: SpellDefines.h:180
#define SPELL_RELIC_COOLDOWN
Definition: SpellMgr.h:34
@ TARGET_FLAG_UNIT_ENEMY
Definition: SpellInfo.h:53
@ TARGET_FLAG_ITEM
Definition: SpellInfo.h:50
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition: SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition: SpellInfo.h:193
@ SPELL_FLAG_REDIRECTED
Definition: Spell.h:83
@ GAMEOBJECT_TYPE_TRAP
Definition: SharedDefines.h:1566
@ GAMEOBJECT_TYPE_DOOR
Definition: SharedDefines.h:1560
Powers
Definition: SharedDefines.h:268
@ POWER_MANA
Definition: SharedDefines.h:269
@ SPELL_ATTR7_DEBUG_SPELL
Definition: SharedDefines.h:644
@ SPELL_EFFECT_LEAP
Definition: SharedDefines.h:807
@ SPELL_EFFECT_POWER_BURN
Definition: SharedDefines.h:840
@ SPELL_EFFECT_STUCK
Definition: SharedDefines.h:862
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition: SharedDefines.h:930
@ SPELL_EFFECT_APPLY_GLYPH
Definition: SharedDefines.h:852
@ SPELL_EFFECT_FEED_PET
Definition: SharedDefines.h:879
@ SPELL_EFFECT_SUMMON_PLAYER
Definition: SharedDefines.h:863
@ SPELL_EFFECT_JUMP_DEST
Definition: SharedDefines.h:820
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition: SharedDefines.h:821
@ SPELL_EFFECT_RESURRECT_PET
Definition: SharedDefines.h:887
@ SPELL_EFFECT_LEAP_BACK
Definition: SharedDefines.h:916
@ SPELL_EFFECT_SUMMON
Definition: SharedDefines.h:806
@ SPELL_EFFECT_POWER_DRAIN
Definition: SharedDefines.h:786
@ SPELL_EFFECT_RESURRECT
Definition: SharedDefines.h:796
@ SPELL_EFFECT_CHARGE
Definition: SharedDefines.h:874
@ SPELL_EFFECT_RESURRECT_NEW
Definition: SharedDefines.h:891
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition: SharedDefines.h:940
@ SPELL_EFFECT_LEARN_SPELL
Definition: SharedDefines.h:814
@ SPELL_EFFECT_JUMP
Definition: SharedDefines.h:819
@ SPELL_EFFECT_SKINNING
Definition: SharedDefines.h:873
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition: SharedDefines.h:931
@ SPELL_EFFECT_OPEN_LOCK
Definition: SharedDefines.h:811
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition: SharedDefines.h:904
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition: SharedDefines.h:835
@ SPELL_PREVENTION_TYPE_NONE
Definition: SharedDefines.h:1553
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition: SharedDefines.h:593
@ TARGET_UNIT_PET
Definition: SharedDefines.h:1414
@ TARGET_GAMEOBJECT_TARGET
Definition: SharedDefines.h:1427
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition: SharedDefines.h:458
@ SPELL_ATTR1_INITIATE_COMBAT
Definition: SharedDefines.h:428
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:504
@ PET_TAME_NOPET_AVAILABLE
Definition: SharedDefines.h:3683
@ PET_TAME_DEAD
Definition: SharedDefines.h:3686
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition: SharedDefines.h:3688
@ CLASS_WARLOCK
Definition: SharedDefines.h:149
@ IMMUNITY_MECHANIC
Definition: SharedDefines.h:1399
@ SPELLFAMILY_WARRIOR
Definition: SharedDefines.h:3532
SpellCustomErrors
Definition: SharedDefines.h:1142
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition: SharedDefines.h:1208
SpellAttr0
Definition: SharedDefines.h:381
@ SPELL_ATTR0_ONLY_INDOORS
Definition: SharedDefines.h:396
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition: SharedDefines.h:408
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition: SharedDefines.h:397
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition: SharedDefines.h:406
@ SPELL_ATTR0_PASSIVE
Definition: SharedDefines.h:388
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition: SharedDefines.h:405
@ SPELL_ATTR0_ONLY_STEALTHED
Definition: SharedDefines.h:399
AuraStateType
Definition: SharedDefines.h:1288
DispelType
Definition: SharedDefines.h:1371
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition: SharedDefines.h:1070
@ SPELL_FAILED_NOT_INFRONT
Definition: SharedDefines.h:1010
@ SPELL_FAILED_MOVING
Definition: SharedDefines.h:1000
@ SPELL_FAILED_NOT_MOUNTED
Definition: SharedDefines.h:1013
@ SPELL_FAILED_AFFECTING_COMBAT
Definition: SharedDefines.h:950
@ SPELL_FAILED_CASTER_AURASTATE
Definition: SharedDefines.h:971
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition: SharedDefines.h:1035
@ SPELL_FAILED_NOT_KNOWN
Definition: SharedDefines.h:1012
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition: SharedDefines.h:984
@ SPELL_FAILED_NOT_HERE
Definition: SharedDefines.h:1009
@ SPELL_FAILED_ROOTED
Definition: SharedDefines.h:1052
@ SPELL_FAILED_WRONG_PET_FOOD
Definition: SharedDefines.h:1084
@ SPELL_FAILED_CUSTOM_ERROR
Definition: SharedDefines.h:1121
@ SPELL_FAILED_SUMMON_PENDING
Definition: SharedDefines.h:1132
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition: SharedDefines.h:1095
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition: SharedDefines.h:960
@ SPELL_FAILED_TRY_AGAIN
Definition: SharedDefines.h:1081
@ SPELL_FAILED_NO_COMBO_POINTS
Definition: SharedDefines.h:1027
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition: SharedDefines.h:956
@ SPELL_FAILED_ALREADY_OPEN
Definition: SharedDefines.h:957
@ SPELL_FAILED_NOT_TRADING
Definition: SharedDefines.h:1020
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition: SharedDefines.h:1036
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition: SharedDefines.h:1032
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition: SharedDefines.h:1115
@ SPELL_FAILED_NOT_BEHIND
Definition: SharedDefines.h:1006
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition: SharedDefines.h:955
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition: SharedDefines.h:1086
@ SPELL_FAILED_HIGHLEVEL
Definition: SharedDefines.h:985
@ SPELL_FAILED_LOWLEVEL
Definition: SharedDefines.h:997
@ SPELL_FAILED_NOT_READY
Definition: SharedDefines.h:1016
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:1091
@ SPELL_FAILED_NOT_IN_ARENA
Definition: SharedDefines.h:1100
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition: SharedDefines.h:991
@ SPELL_FAILED_ONLY_STEALTHED
Definition: SharedDefines.h:1044
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition: SharedDefines.h:1067
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition: SharedDefines.h:1037
@ SPELL_FAILED_CANT_BE_CHARMED
Definition: SharedDefines.h:962
@ SPELL_FAILED_CASTER_DEAD
Definition: SharedDefines.h:972
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition: SharedDefines.h:1104
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition: SharedDefines.h:1131
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition: SharedDefines.h:1135
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition: SharedDefines.h:1075
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition: SharedDefines.h:1017
@ SPELL_FAILED_UNIQUE_GLYPH
Definition: SharedDefines.h:1125
@ SPELL_FAILED_ONLY_OUTDOORS
Definition: SharedDefines.h:1042
@ SPELL_FAILED_CHARMED
Definition: SharedDefines.h:973
@ SPELL_FAILED_LINE_OF_SIGHT
Definition: SharedDefines.h:996
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition: SharedDefines.h:1054
@ SPELL_FAILED_NO_PET
Definition: SharedDefines.h:1033
@ SPELL_FAILED_NOPATH
Definition: SharedDefines.h:1005
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition: SharedDefines.h:1056
@ SPELL_FAILED_ONLY_INDOORS
Definition: SharedDefines.h:1039
@ SPELL_FAILED_NOT_ON_TAXI
Definition: SharedDefines.h:1014
@ SPELL_FAILED_TARGET_FRIENDLY
Definition: SharedDefines.h:1064
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition: SharedDefines.h:547
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition: SharedDefines.h:546
@ SUMMON_CATEGORY_PET
Definition: SharedDefines.h:3285
@ SUMMON_CATEGORY_PUPPET
Definition: SharedDefines.h:3286
SkillType
Definition: SharedDefines.h:2863
@ SKILL_MINING
Definition: SharedDefines.h:2919
@ SKILL_HERBALISM
Definition: SharedDefines.h:2915
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition: SharedDefines.h:616
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition: DBCEnums.h:456
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition: DBCEnums.h:457
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:458
Difficulty
Definition: DBCEnums.h:266
@ AREA_FLAG_NO_FLY_ZONE
Definition: DBCEnums.h:262
bool IsPathfindingEnabled(const Map *map)
Definition: DisableMgr.cpp:411
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:248
Seconds GetGameTime()
Definition: GameTime.cpp:38
Definition: Battlefield.h:204
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition: Battlefield.h:340
Definition: Battleground.h:303
Definition: ConditionMgr.h:181
Condition * mLastFailedCondition
Definition: ConditionMgr.h:183
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition: ConditionMgr.h:182
uint32 ErrorType
Definition: ConditionMgr.h:204
uint8 ConditionTarget
Definition: ConditionMgr.h:208
uint32 ErrorTextId
Definition: ConditionMgr.h:205
Loot loot
Definition: Creature.h:229
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:208
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition: Creature.cpp:2827
SkillType GetRequiredLootSkill() const
Definition: CreatureData.h:258
bool IsTameable(bool exotic) const
Definition: CreatureData.h:275
Definition: TemporarySummon.h:40
Definition: GameObject.h:121
GameObjectTemplate const * GetGOInfo() const
Definition: GameObject.h:137
uint32 type
Definition: GameObjectData.h:33
bool IsLocked() const
Definition: Item.h:253
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:545
bool IsPotion() const
Definition: Item.h:337
uint32 ItemLevel
Definition: ItemTemplate.h:635
uint32 LockID
Definition: ItemTemplate.h:669
uint32 InventoryType
Definition: ItemTemplate.h:632
Unit * ToUnit()
Definition: Object.h:206
Map * GetMap() const
Definition: Object.h:531
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1192
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }, Optional< float > combatReach={ }) const
Definition: Object.cpp:1347
bool IsOutdoors() const
Definition: Object.cpp:3171
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition: Object.cpp:1326
float GetVisibilityRange() const
Definition: Object.cpp:1645
uint32 GetAreaId() const
Definition: Object.cpp:3154
uint32 GetZoneId() const
Definition: Object.cpp:3146
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition: Object.cpp:3162
uint64 GetRawValue() const
Definition: ObjectGuid.h:142
bool IsPlayer() const
Definition: ObjectGuid.h:168
bool IsGameObject() const
Definition: ObjectGuid.h:171
void GetPosition(float &x, float &y) const
Definition: Position.h:122
uint32 GetMapId() const
Definition: Position.h:276
Player * GetOwner() const
Definition: Pet.cpp:2493
bool HaveInDiet(ItemTemplate const *item) const
Definition: Pet.cpp:1439
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition: Pet.cpp:1457
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition: Pet.cpp:170
Definition: PetDefines.h:202
Optional< PetInfo > CurrentPet
Definition: PetDefines.h:225
std::vector< PetInfo > UnslottedPets
Definition: PetDefines.h:228
void SetCanTeleport(bool value)
Definition: Player.h:2480
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1868
bool CanTameExoticPets() const
Definition: Player.h:2171
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition: Player.cpp:13221
bool InBattleground() const
Definition: Player.h:2234
PetStable * GetPetStable()
Definition: Player.h:1202
Battleground * GetBattleground(bool create=false) const
Definition: Player.cpp:12195
WorldSession * GetSession() const
Definition: Player.h:1980
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Player.cpp:16337
uint32 GetLastPotionId()
Definition: Player.h:1794
Group * GetGroup()
Definition: Player.h:2450
bool IsGameMaster() const
Definition: Player.h:1158
time_t GetSummonExpireTimer() const
Definition: Player.h:1101
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition: PlayerStorage.cpp:6707
bool HasPlayerFlag(PlayerFlags flags) const
Definition: Player.h:1108
std::unique_ptr< DuelInfo > duel
Definition: Player.h:1860
Item * GetItemByGuid(ObjectGuid guid) const
Definition: PlayerStorage.cpp:409
uint32 GetSpell() const
Definition: TradeData.h:49
bool IsVehicle() const
Definition: Unit.h:713
Vehicle * GetVehicle() const
Definition: Unit.h:1687
Unit * GetOwner() const
Definition: Unit.cpp:10561
Pet * ToPet()
Definition: Unit.h:1728
virtual bool HasSpellCooldown(uint32) const
Definition: Unit.h:1741
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:1475
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition: Unit.h:1742
bool IsInDisallowedMountForm() const
Definition: Unit.cpp:21226
void CombatStart(Unit *target, bool initialAggro=true)
Definition: Unit.cpp:13585
bool HasUnitFlag2(UnitFlags2 flags) const
Definition: Unit.h:688
bool IsInSanctuary() const
Definition: Unit.h:964
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition: Unit.h:748
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition: Unit.cpp:5779
float GetCombatReach() const override
Definition: Unit.h:770
UnitFlags GetUnitFlags() const
Definition: Unit.h:681
TempSummon * ToTempSummon()
Definition: Unit.h:1730
bool HasStealthAura() const
Definition: Unit.h:1115
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5668
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition: Unit.h:652
bool IsInFlight() const
Definition: Unit.h:1108
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition: Unit.h:1811
void SendTameFailure(uint8 result)
Definition: Unit.cpp:19966
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:1627
virtual bool IsInWater() const
Definition: Unit.cpp:4320
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:10508
bool isMoving() const
Definition: Unit.h:1710
ObjectGuid GetCharmGUID() const
Definition: Unit.h:1230
VisibleAuraMap const * GetVisibleAuras()
Definition: Unit.h:1504
bool IsMounted() const
Definition: Unit.h:990
Unit * GetVictim() const
Definition: Unit.h:789
bool IsCritter() const
Definition: Unit.h:1106
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:1222
uint8 GetComboPoints(Unit const *who=nullptr) const
--------—Combo point system----------------—
Definition: Unit.h:1643
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:1228
uint32 getTransForm() const
Definition: Unit.h:1527
virtual bool HasActivePowerType(Powers power)
Definition: Unit.h:890
void RemoveMovementImpairingAuras(bool withRoot)
Definition: Unit.cpp:5204
bool IsTotem() const
Definition: Unit.h:712
Guardian * GetGuardianPet() const
Definition: Unit.cpp:10612
ObjectGuid GetTarget() const
Definition: Unit.h:1756
bool IsInCombat() const
Definition: Unit.h:820
ObjectGuid GetPetGUID() const
Definition: Unit.h:1232
Definition: Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition: Vehicle.cpp:580
Definition: Group.h:169
Definition: GroupReference.h:27
GroupReference * next()
Definition: GroupReference.h:36
Definition: InstanceScript.h:142
bool isLooted() const
Definition: LootMgr.h:368
Definition: Map.h:274
bool AllowMount
Definition: Map.h:277
bool IsDungeon() const
Definition: Map.h:448
bool IsBattlegroundOrArena() const
Definition: Map.h:456
GameObject * GetGameObject(ObjectGuid const guid)
Definition: Map.cpp:3319
uint32 GetId() const
Definition: Map.h:379
Difficulty GetDifficulty() const
Definition: Map.h:443
uint32 GetRecruiterId() const
Definition: WorldSession.h:526
uint32 GetAccountId() const
Definition: WorldSession.h:361
GameObject * GetGOTarget() const
Definition: Spell.cpp:265
ObjectGuid GetItemTargetGUID() const
Definition: Spell.h:138
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition: Spell.h:776
SpellCastResult CheckSpellFocus()
Definition: Spell.cpp:7745
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition: Spell.cpp:8357
SpellCastResult CheckItems()
Definition: Spell.cpp:7177
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition: Spell.h:477
SpellCastResult CheckPower()
Definition: Spell.cpp:7132
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition: Spell.cpp:6849
SpellCastResult CallScriptCheckCastHandlers()
Definition: Spell.cpp:8556
bool IsTriggered() const
Definition: Spell.h:552
SpellCastResult CheckRange(bool strict)
Definition: Spell.cpp:7046
bool HasGlobalCooldown() const
Definition: Spell.cpp:8828
Definition: SpellInfo.h:249
int32 MiscValue
Definition: SpellInfo.h:263
uint32 ApplyAuraName
Definition: SpellInfo.h:254
uint32 PreventionType
Definition: SpellInfo.h:390
uint32 CasterAuraSpell
Definition: SpellInfo.h:343
SpellCastResult CheckShapeshift(uint32 form) const
Definition: SpellInfo.cpp:1433
uint32 Mechanic
Definition: SpellInfo.h:323
uint32 GetDispelMask() const
Definition: SpellInfo.cpp:2040
uint32 GetRecoveryTime() const
Definition: SpellInfo.cpp:2395
bool IsSelfCast() const
Definition: SpellInfo.cpp:1089
uint32 CasterAuraState
Definition: SpellInfo.h:339
bool CanBeUsedInCombat() const
Definition: SpellInfo.cpp:1231
uint32 CasterAuraStateNot
Definition: SpellInfo.h:341
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player *player=nullptr, bool strict=true) const
Definition: SpellInfo.cpp:1488
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:1986
int32 AreaGroupId
Definition: SpellInfo.h:391
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2322
uint32 GetExplicitTargetMask() const
Definition: SpellInfo.cpp:2054
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1032
uint32 ExcludeCasterAuraSpell
Definition: SpellInfo.h:345
uint32 SpellFamilyName
Definition: SpellInfo.h:387
uint32 AuraInterruptFlags
Definition: SpellInfo.h:353
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition: SpellInfo.cpp:1936
Definition: DBCStructure.h:518
Definition: DBCStructure.h:1020
Definition: DBCStructure.h:1324
bool IsDungeon() const
Definition: DBCStructure.h:1350
Definition: DBCStructure.h:1816
uint32 flags1
Definition: DBCStructure.h:1821
Definition: DBCStructure.h:1908
uint32 Category
Definition: DBCStructure.h:1910
Definition: DBCStructure.h:2063
uint32 m_flags
Definition: DBCStructure.h:2065

References InstanceTemplate::AllowMount, SpellEffectInfo::ApplyAuraName, AREA_FLAG_NO_FLY_ZONE, SpellInfo::AreaGroupId, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellInfo::AuraInterruptFlags, CalculateSpellDamage(), CallScriptCheckCastHandlers(), SpellInfo::CanBeUsedInCombat(), Battlefield::CanFlyIn(), CanOpenLock(), Player::CanTameExoticPets(), Player::CanUseBattlegroundObject(), SpellInfo::CasterAuraSpell, SpellInfo::CasterAuraState, SpellInfo::CasterAuraStateNot, SummonPropertiesEntry::Category, CheckCasterAuras(), SpellInfo::CheckExplicitTarget(), CheckItems(), SpellInfo::CheckLocation(), CheckPower(), CheckRange(), SpellInfo::CheckShapeshift(), CheckSpellFocus(), SpellInfo::CheckTarget(), CLASS_CONTEXT_PET, CLASS_WARLOCK, Unit::CombatStart(), CONDITION_SOURCE_TYPE_SPELL, Condition::ConditionTarget, PetStable::CurrentPet, damage, Player::duel, EFFECT_0, SpellInfo::Effects, Condition::ErrorTextId, Condition::ErrorType, SpellInfo::ExcludeCasterAuraSpell, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), SpellShapeshiftFormEntry::flags1, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_TRAP, WorldSession::GetAccountId(), WorldObject::GetAreaId(), Unit::GetAuraEffectsByType(), Player::GetBattleground(), Unit::GetCharm(), Unit::GetCharmerGUID(), Unit::GetCharmGUID(), Unit::GetCombatReach(), Unit::GetComboPoints(), Creature::GetCreatureTemplate(), Pet::GetCurrentFoodBenefitLevel(), Map::GetDifficulty(), SpellInfo::GetDispelMask(), WorldObject::GetDistance(), SpellCastTargets::GetDstPos(), Object::GetEntry(), SpellInfo::GetExplicitTargetMask(), Map::GetGameObject(), GameTime::GetGameTime(), GameObject::GetGOInfo(), SpellCastTargets::GetGOTarget(), Player::GetGroup(), Unit::GetGuardianPet(), Map::GetId(), WorldObject::GetInstanceScript(), Player::GetItemByGuid(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetGUID(), Player::GetLastPotionId(), Unit::GetLevel(), Pet::GetLoadPetInfo(), WorldObject::GetMap(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellCastTargets::GetObjectTarget(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Player::GetPetStable(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), ObjectGuid::GetRawValue(), SpellInfo::GetRecoveryTime(), WorldSession::GetRecruiterId(), CreatureTemplate::GetRequiredLootSkill(), SpellInfo::GetSchoolMask(), Vehicle::GetSeatForPassenger(), Player::GetSession(), Unit::GetShapeshiftForm(), Player::GetSkillValue(), TradeData::GetSpell(), Player::GetSummonExpireTimer(), Unit::GetTarget(), SpellCastTargets::GetTargetMask(), Item::GetTemplate(), Player::GetTradeData(), Unit::getTransForm(), Unit::GetUnitFlags(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicle(), Unit::GetVictim(), WorldObject::GetVisibilityRange(), Unit::GetVisibleAuras(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), GO_STATE_READY, Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasGlobalCooldown(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasSpellItemCooldown(), Unit::HasStealthAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag2(), Unit::HasUnitMovementFlag(), Unit::HasUnitState(), Pet::HaveInDiet(), HUNTER_PET, SpellInfo::Id, IMMUNITY_MECHANIC, IN_MILLISECONDS, Player::InBattleground(), ItemTemplate::InventoryType, INVTYPE_RELIC, irand(), Unit::IsAlive(), IsAutoRepeat(), Map::IsBattlegroundOrArena(), Unit::IsClass(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsCritter(), Map::IsDungeon(), MapEntry::IsDungeon(), Unit::IsFriendlyTo(), Player::IsGameMaster(), ObjectGuid::IsGameObject(), Unit::IsInCombat(), Unit::IsInDisallowedMountForm(), Unit::IsInFlight(), Player::IsInSameRaidWith(), Unit::IsInSanctuary(), Unit::IsInWater(), Item::IsLocked(), Loot::isLooted(), Unit::IsMounted(), Unit::isMoving(), IsNextMeleeSwingSpell(), WorldObject::IsOutdoors(), SpellInfo::IsPassive(), DisableMgr::IsPathfindingEnabled(), Object::IsPlayer(), SpellInfo::IsPositive(), Item::IsPotion(), Unit::IsScriptOverriden(), SpellInfo::IsSelfCast(), Creature::IsSpellProhibited(), CreatureTemplate::IsTameable(), Unit::IsTotem(), IsTriggered(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), ItemTemplate::ItemLevel, LINEOFSIGHT_ALL_CHECKS, ItemTemplate::LockID, Creature::loot, VMAP::M2, m_caster, m_CastItem, m_customError, VehicleSeatEntry::m_flags, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_preGeneratedPath, m_selfContainer, m_spellFlags, Unit::m_spellImmune, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, ConditionSourceInfo::mConditionTargets, SpellInfo::Mechanic, MINUTE, SpellEffectInfo::MiscValue, ConditionSourceInfo::mLastFailedCondition, MOVEMENTFLAG_FALLING_FAR, SpellInfo::NeedsExplicitUnitTarget(), GroupReference::next(), PATHFIND_INCOMPLETE, PATHFIND_NOPATH, PATHFIND_SHORT, PET_TAME_CANT_CONTROL_EXOTIC, PET_TAME_DEAD, PET_TAME_NOPET_AVAILABLE, PLAYER_ALLOW_ONLY_ABILITY, POWER_MANA, SpellInfo::PreventionType, Unit::RemoveMovementImpairingAuras(), sAreaTableStore, Player::Satisfy(), sBattlefieldMgr, sConditionMgr, Unit::SendTameFailure(), sGlyphPropertiesStore, SKILL_HERBALISM, SKILL_LOCKPICKING, SKILL_MINING, SKILL_NONE, sMapStore, sObjectMgr, SPECTATOR_SPELL_BINDSIGHT, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_WHILE_MOUNTED, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET, SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_ONLY_INDOORS, SPELL_ATTR0_ONLY_OUTDOORS, SPELL_ATTR0_ONLY_STEALTHED, SPELL_ATTR0_PASSIVE, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR1_INITIATE_COMBAT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR3_ONLY_BATTLEGROUNDS, SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS, SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND, SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT, SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE, SPELL_ATTR7_DEBUG_SPELL, SPELL_AURA_ABILITY_IGNORE_AURASTATE, SPELL_AURA_AOE_CHARM, SPELL_AURA_BLOCK_SPELL_FAMILY, SPELL_AURA_DUMMY, SPELL_AURA_FLY, SPELL_AURA_HOVER, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_IGNORE_SHAPESHIFT, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOD_SHAPESHIFT, SPELL_AURA_MOUNTED, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS, SPELL_CAST_OK, SPELL_CUSTOM_ERROR_GM_ONLY, SPELL_EFFECT_APPLY_GLYPH, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CREATE_TAMED_PET, SPELL_EFFECT_DISPEL, SPELL_EFFECT_FEED_PET, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_LEARN_PET_SPELL, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_OPEN_LOCK, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_RESURRECT, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_RESURRECT_PET, SPELL_EFFECT_SKINNING, SPELL_EFFECT_STEAL_BENEFICIAL_BUFF, SPELL_EFFECT_STUCK, SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_EFFECT_TALENT_SPEC_SELECT, SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER, SPELL_FAILED_AFFECTING_COMBAT, SPELL_FAILED_ALREADY_HAVE_CHARM, SPELL_FAILED_ALREADY_HAVE_SUMMON, SPELL_FAILED_ALREADY_OPEN, SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_CHARMED, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_CHARMED, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_DAMAGE_IMMUNE, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_FOOD_LOWLEVEL, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_ALREADY_ENCHANTED, SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MOVING, SPELL_FAILED_NO_COMBO_POINTS, SPELL_FAILED_NO_MOUNTS_ALLOWED, SPELL_FAILED_NO_PET, SPELL_FAILED_NOPATH, SPELL_FAILED_NOT_BEHIND, SPELL_FAILED_NOT_HERE, SPELL_FAILED_NOT_IN_ARENA, SPELL_FAILED_NOT_IN_BATTLEGROUND, SPELL_FAILED_NOT_INFRONT, SPELL_FAILED_NOT_KNOWN, SPELL_FAILED_NOT_MOUNTED, SPELL_FAILED_NOT_ON_MOUNTED, SPELL_FAILED_NOT_ON_TAXI, SPELL_FAILED_NOT_READY, SPELL_FAILED_NOT_SHAPESHIFT, SPELL_FAILED_NOT_TRADING, SPELL_FAILED_NOTHING_TO_DISPEL, SPELL_FAILED_NOTHING_TO_STEAL, SPELL_FAILED_ONLY_ABOVEWATER, SPELL_FAILED_ONLY_BATTLEGROUNDS, SPELL_FAILED_ONLY_INDOORS, SPELL_FAILED_ONLY_OUTDOORS, SPELL_FAILED_ONLY_STEALTHED, SPELL_FAILED_ROOTED, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_SUMMON_PENDING, SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED, SPELL_FAILED_TARGET_NOT_IN_INSTANCE, SPELL_FAILED_TARGET_NOT_LOOTED, SPELL_FAILED_TARGET_UNSKINNABLE, SPELL_FAILED_TRY_AGAIN, SPELL_FAILED_UNIQUE_GLYPH, SPELL_FAILED_WRONG_PET_FOOD, SPELL_FLAG_REDIRECTED, SPELL_PREVENTION_TYPE_NONE, SPELL_RELIC_COOLDOWN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyName, TriggeredByAuraSpellData::spellInfo, SpellInfo::SpellLevel, sScriptMgr, sSpellMgr, sSpellShapeshiftFormStore, sSummonPropertiesStore, STATUS_IN_PROGRESS, STATUS_WAIT_LEAVE, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, TARGET_FLAG_ITEM, TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT_ENEMY, TARGET_GAMEOBJECT_ITEM_TARGET, TARGET_GAMEOBJECT_TARGET, TARGET_UNIT_PET, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), Unit::ToTempSummon(), Object::ToUnit(), TRADE_SLOT_NONTRADED, TRIGGERED_IGNORE_CASTER_AURAS, TRIGGERED_IGNORE_CASTER_AURASTATE, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE, TRIGGERED_IGNORE_EFFECTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SHAPESHIFT, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, GameObjectTemplate::type, UNIT_FLAG2_ALLOW_CHEAT_SPELLS, UNIT_FLAG_SKINNABLE, UNIT_STATE_CHARGING, UNIT_STATE_ROOT, unitTarget, PetStable::UnslottedPets, VEHICLE_SEAT_FLAG_CAN_ATTACK, VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL, VEHICLE_SEAT_FLAG_UNCONTROLLED, and WORLD_TRIGGER.

Referenced by _cast(), Unit::_UpdateAutoRepeatSpell(), Unit::AttackerStateUpdate(), Player::CastItemUseSpell(), CheckPetCast(), WorldSession::HandleAcceptTradeOpcode(), prepare(), and go_wind_stone::go_wind_stoneAI::SummonNPC().

◆ CheckCasterAuras()

SpellCastResult Spell::CheckCasterAuras ( bool  preventionOnly) const
6850{
6851 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6853 return SPELL_CAST_OK;
6854
6855 uint8 school_immune = 0;
6856 uint32 mechanic_immune = 0;
6857 uint32 dispel_immune = 0;
6858
6859 // Check if the spell grants school or mechanic immunity.
6860 // We use bitmasks so the loop is done only once and not on every aura check below.
6862 {
6863 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6864 {
6865 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6866 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6867 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6868 mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
6869 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6870 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6871 }
6872 // immune movement impairment and loss of control
6873 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6874 if (m_spellInfo->Id == 42292 || m_spellInfo->Id == 59752 || m_spellInfo->Id == 65547 || m_spellInfo->Id == 53490 || m_spellInfo->Id == 19574 || m_spellInfo->Id == 34471 || m_spellInfo->Id == 46227)
6876 }
6877
6879
6880 // Glyph of Pain Suppression
6881 // there is no other way to handle it
6882 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6883 usableInStun = false;
6884
6885 // Check whether the cast should be prevented by any state you might have.
6886 SpellCastResult prevented_reason = SPELL_CAST_OK;
6887 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6888 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6889
6890 // Xinef: if spell is triggered check preventionType only
6891 if (!preventionOnly)
6892 {
6893 if (unitflag & UNIT_FLAG_STUNNED)
6894 {
6895 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6896 if (usableInStun)
6897 {
6898 bool foundNotStun = false;
6899 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6900 // Barkskin should skip sleep effects, sap and fears
6901 if (m_spellInfo->Id == 22812)
6902 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6903 // Hand of Freedom, can be used while sapped
6904 if (m_spellInfo->Id == 1044)
6905 mask |= 1 << MECHANIC_SAPPED;
6907 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6908 {
6909 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6910 {
6911 foundNotStun = true;
6912 break;
6913 }
6914 }
6915 if (foundNotStun)
6916 prevented_reason = SPELL_FAILED_STUNNED;
6917 }
6918 else
6919 prevented_reason = SPELL_FAILED_STUNNED;
6920 }
6922 prevented_reason = SPELL_FAILED_CONFUSED;
6924 prevented_reason = SPELL_FAILED_FLEEING;
6925 }
6926
6927 // Xinef: if there is no prevented_reason, check prevention types
6928 if (prevented_reason == SPELL_CAST_OK)
6929 {
6931 prevented_reason = SPELL_FAILED_SILENCED;
6933 prevented_reason = SPELL_FAILED_PACIFIED;
6934 }
6935
6936 // Attr must make flag drop spell totally immune from all effects
6937 if (prevented_reason != SPELL_CAST_OK)
6938 {
6939 if (school_immune || mechanic_immune || dispel_immune)
6940 {
6941 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6943 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6944 {
6945 Aura const* aura = itr->second->GetBase();
6946 SpellInfo const* auraInfo = aura->GetSpellInfo();
6947 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6948 continue;
6949 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6950 continue;
6951 if (auraInfo->GetDispelMask() & dispel_immune)
6952 continue;
6953
6954 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6955 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6956 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6957 {
6958 if (AuraEffect* part = aura->GetEffect(i))
6959 {
6960 switch (part->GetAuraType())
6961 {
6963 {
6964 uint32 mask = 1 << MECHANIC_STUN;
6965 // Barkskin should skip sleep effects, sap and fears
6966 if (m_spellInfo->Id == 22812)
6967 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6968 // Hand of Freedom, can be used while sapped
6969 if (m_spellInfo->Id == 1044)
6970 mask |= 1 << MECHANIC_SAPPED;
6971
6972 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6973 return SPELL_FAILED_STUNNED;
6974 break;
6975 }
6978 return SPELL_FAILED_CONFUSED;
6979 break;
6982 return SPELL_FAILED_FLEEING;
6983 break;
6988 return SPELL_FAILED_PACIFIED;
6990 return SPELL_FAILED_SILENCED;
6991 break;
6992 default:
6993 break;
6994 }
6995 }
6996 }
6997 }
6998 }
6999 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
7000 else
7001 return prevented_reason;
7002 }
7003 return SPELL_CAST_OK;
7004}
@ UNIT_FLAG_STUNNED
Definition: UnitDefines.h:247
@ UNIT_FLAG_PACIFIED
Definition: UnitDefines.h:246
@ UNIT_FLAG_CONFUSED
Definition: UnitDefines.h:251
@ UNIT_FLAG_FLEEING
Definition: UnitDefines.h:252
@ UNIT_FLAG_SILENCED
Definition: UnitDefines.h:242
@ SPELL_AURA_DISPEL_IMMUNITY
Definition: SpellAuraDefines.h:104
@ SPELL_AURA_MOD_FEAR
Definition: SpellAuraDefines.h:70
@ SPELL_AURA_MOD_PACIFY
Definition: SpellAuraDefines.h:88
@ SPELL_AURA_MOD_SILENCE
Definition: SpellAuraDefines.h:90
@ SPELL_AURA_SCHOOL_IMMUNITY
Definition: SpellAuraDefines.h:102
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition: SpellAuraDefines.h:140
@ SPELL_AURA_MOD_PACIFY_SILENCE
Definition: SpellAuraDefines.h:123
@ SPELL_AURA_MOD_CONFUSE
Definition: SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition: SpellAuraDefines.h:75
@ SPELL_PREVENTION_TYPE_SILENCE
Definition: SharedDefines.h:1554
@ SPELL_PREVENTION_TYPE_PACIFY
Definition: SharedDefines.h:1555
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition: SharedDefines.h:570
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition: SharedDefines.h:584
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition: SharedDefines.h:585
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition: SharedDefines.h:434
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition: SharedDefines.h:435
@ MECHANIC_STUN
Definition: SharedDefines.h:1337
@ MECHANIC_FREEZE
Definition: SharedDefines.h:1338
@ MECHANIC_SLEEP
Definition: SharedDefines.h:1335
@ MECHANIC_SAPPED
Definition: SharedDefines.h:1355
@ MECHANIC_HORROR
Definition: SharedDefines.h:1349
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition: SharedDefines.h:1361
@ SPELL_FAILED_STUNNED
Definition: SharedDefines.h:1057
@ SPELL_FAILED_CONFUSED
Definition: SharedDefines.h:975
@ SPELL_FAILED_SILENCED
Definition: SharedDefines.h:1053
@ SPELL_FAILED_FLEEING
Definition: SharedDefines.h:983
@ SPELL_FAILED_PACIFIED
Definition: SharedDefines.h:1047
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition: SharedDefines.h:606
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition: Unit.h:639
AuraApplicationMap & GetAppliedAuras()
Definition: Unit.h:1331
Definition: SpellAuras.h:87
AuraEffect * GetEffect(uint8 effIndex) const
Definition: SpellAuras.h:175
SpellInfo const * GetSpellInfo() const
Definition: SpellAuras.h:100
uint32 GetAllEffectsMechanicMask() const
Definition: SpellInfo.cpp:1991

References SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), Unit::GetAuraEffectsByType(), SpellInfo::GetDispelMask(), Aura::GetEffect(), SpellInfo::GetSchoolMask(), Aura::GetSpellInfo(), Unit::GetUnitFlags(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK, m_caster, m_spellInfo, MAX_SPELL_EFFECTS, MECHANIC_FREEZE, MECHANIC_HORROR, MECHANIC_SAPPED, MECHANIC_SLEEP, MECHANIC_STUN, SpellInfo::PreventionType, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS, SPELL_ATTR5_ALLOW_WHILE_CONFUSED, SPELL_ATTR5_ALLOW_WHILE_FLEEING, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR6_NOT_AN_ATTACK, SPELL_AURA_DISPEL_IMMUNITY, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_PACIFY, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_STUN, SPELL_AURA_SCHOOL_IMMUNITY, SPELL_CAST_OK, SPELL_FAILED_CONFUSED, SPELL_FAILED_FLEEING, SPELL_FAILED_PACIFIED, SPELL_FAILED_SILENCED, SPELL_FAILED_STUNNED, SPELL_PREVENTION_TYPE_PACIFY, SPELL_PREVENTION_TYPE_SILENCE, UNIT_FLAG_CONFUSED, UNIT_FLAG_FLEEING, UNIT_FLAG_PACIFIED, UNIT_FLAG_SILENCED, and UNIT_FLAG_STUNNED.

Referenced by CheckCast().

◆ CheckDst()

void Spell::CheckDst ( )
inline
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition: Spell.cpp:407

References SpellCastTargets::HasDst(), m_caster, m_targets, and SpellCastTargets::SetDst().

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8490{
8491 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8493}
#define ASSERT
Definition: Errors.h:68

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by PrepareTargetProcessing(), and ~Spell().

◆ CheckEffectTarget()

bool Spell::CheckEffectTarget ( Unit const *  target,
uint32  eff 
) const
Todo:
: below shouldn't be here, but it's temporary
7923{
7924 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7925 {
7930 if (target->IsCreature() && target->IsVehicle())
7931 return false;
7932 if (target->IsMounted())
7933 return false;
7934 if (target->GetCharmerGUID())
7935 return false;
7936 if (int32 damage = CalculateSpellDamage(eff, target))
7937 if ((int32)target->GetLevel() > damage)
7938 return false;
7939 break;
7940 default:
7941 break;
7942 }
7943
7944 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7945 // this is only for target addition and target has to have unselectable flag, this is valid for FLAG_EXTRA_TRIGGER and quest triggers however there are some without this flag, used not_selectable
7946 if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) || (target->IsCreature() && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && (m_spellInfo->Effects[eff].TargetA.GetCheckType() == TARGET_CHECK_ENTRY || m_spellInfo->Effects[eff].TargetB.GetCheckType() == TARGET_CHECK_ENTRY)))
7947 return true;
7948
7949 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7952 {
7953 return true;
7954 }
7955
7957 //Check targets for LOS visibility (except spells without range limitations)
7958 switch (m_spellInfo->Effects[eff].Effect)
7959 {
7961 // player far away, maybe his corpse near?
7962 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
7963 {
7965 return false;
7966
7968 if (!corpse)
7969 return false;
7970
7971 if (target->GetGUID() != corpse->GetOwnerGUID())
7972 return false;
7973
7975 return false;
7976 }
7977 break;
7979 {
7981 {
7982 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
7983 return true;
7984
7985 return false;
7986 }
7987
7989 if (!corpse)
7990 return false;
7991
7992 if (target->GetGUID() != corpse->GetOwnerGUID())
7993 return false;
7994
7996 return false;
7997
7999 return false;
8000 }
8001 break;
8003 if (!m_caster->IsPlayer() || !target->IsPlayer())
8004 return false;
8005 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
8006 return false;
8007 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8008 return false;
8009 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8010 return false;
8011 break;
8012 default: // normal case
8013 {
8014 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8015 GameObject* gobCaster = nullptr;
8017 {
8019 }
8020 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8021 {
8022 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8023 {
8024 gobCaster = tempSummon->GetSummonerGameObject();
8025 }
8026 }
8027
8028 if (gobCaster)
8029 {
8030 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8031 {
8032 return true;
8033 }
8034
8035 // If spell casted by gameobject then ignore M2 models
8036 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8037 }
8038
8039 if (target != m_caster)
8040 {
8041 if (m_targets.HasDst())
8042 {
8043 float x = m_targets.GetDstPos()->GetPositionX();
8044 float y = m_targets.GetDstPos()->GetPositionY();
8045 float z = m_targets.GetDstPos()->GetPositionZ();
8046
8047 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8048 {
8049 return false;
8050 }
8051 }
8053 {
8054 return false;
8055 }
8056 }
8057 break;
8058 }
8059 }
8060
8061 return true;
8062}
@ SPELL_DISABLE_LOS
Definition: DisableMgr.h:50
@ DISABLE_TYPE_SPELL
Definition: DisableMgr.h:29
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition: IWorld.h:251
@ CORPSE_FLAG_LOOTABLE
Definition: Corpse.h:45
@ UNIT_FLAG_NOT_SELECTABLE
Definition: UnitDefines.h:254
@ CORPSE_FIELD_FLAGS
Definition: UpdateFields.h:427
@ TARGET_CHECK_ENTRY
Definition: SpellInfo.h:115
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition: SharedDefines.h:894
#define sWorld
Definition: World.h:444
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
Definition: DisableMgr.cpp:306
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:182
Definition: Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition: Corpse.h:68
bool IsIgnoringLOSChecks() const
Definition: GameObjectData.h:642
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.cpp:889
bool IsARecruiter() const
Definition: WorldSession.h:527
ObjectGuid GetCorpseTargetGUID() const
Definition: Spell.cpp:282

References CalculateSpellDamage(), CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, CORPSE_FIELD_FLAGS, CORPSE_FLAG_LOOTABLE, damage, DISABLE_TYPE_SPELL, SpellInfo::Effects, WorldSession::GetAccountId(), Unit::GetCharmerGUID(), ObjectAccessor::GetCorpse(), SpellCastTargets::GetCorpseTargetGUID(), SpellCastTargets::GetDstPos(), Object::GetEntry(), Map::GetGameObject(), GameObject::GetGOInfo(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Corpse::GetOwnerGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldSession::GetRecruiterId(), Player::GetSession(), SpellInfo::HasAttribute(), SpellCastTargets::HasDst(), Object::HasFlag(), Unit::HasUnitFlag(), SpellInfo::Id, WorldSession::IsARecruiter(), Object::IsCreature(), DisableMgr::IsDisabledFor(), ObjectGuid::IsGameObject(), GameObjectTemplate::IsIgnoringLOSChecks(), Unit::IsMounted(), Object::IsPlayer(), IsTriggered(), Unit::IsVehicle(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), LINEOFSIGHT_ALL_CHECKS, VMAP::M2, m_caster, m_originalCasterGUID, m_spellFlags, m_spellInfo, m_targets, m_triggeredByAuraSpell, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_AURA_AOE_CHARM, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_DISABLE_LOS, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_SKIN_PLAYER_CORPSE, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_FLAG_REDIRECTED, TriggeredByAuraSpellData::spellInfo, sWorld, TARGET_CHECK_ENTRY, Object::ToPlayer(), Unit::ToTempSummon(), UNIT_FLAG_NOT_SELECTABLE, UNIT_FLAG_SKINNABLE, and WORLD_TRIGGER.

Referenced by AddUnitTarget().

◆ CheckItems()

SpellCastResult Spell::CheckItems ( )
Todo:
Needs review
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7178{
7179 Player* player = m_caster->ToPlayer();
7180 if (!player)
7181 {
7182 // Non-player case: Check if creature is disarmed
7184 {
7186 }
7187
7188 return SPELL_CAST_OK;
7189 }
7190
7191 if (!m_CastItem)
7192 {
7193 if (m_castItemGUID)
7195 }
7196 else
7197 {
7198 uint32 itemid = m_CastItem->GetEntry();
7199 if (!player->HasItemCount(itemid))
7201
7202 ItemTemplate const* proto = m_CastItem->GetTemplate();
7203 if (!proto)
7205
7206 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7207 if (proto->Spells[i].SpellCharges)
7208 if (m_CastItem->GetSpellCharges(i) == 0)
7210
7211 // consumable cast item checks
7213 {
7214 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7215 SpellCastResult failReason = SPELL_CAST_OK;
7216 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7217 {
7218 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7219 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7220 continue;
7221
7222 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7223 {
7225 {
7227 continue;
7228 }
7229 else
7230 {
7231 failReason = SPELL_CAST_OK;
7232 break;
7233 }
7234 }
7235
7236 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7237 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7238 {
7239 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7240 {
7242 continue;
7243 }
7244
7245 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7247 {
7249 continue;
7250 }
7251 else
7252 {
7253 failReason = SPELL_CAST_OK;
7254 break;
7255 }
7256 }
7257 }
7258 if (failReason != SPELL_CAST_OK)
7259 return failReason;
7260 }
7261 }
7262
7263 // check target item
7265 {
7266 if (!m_caster->IsPlayer())
7268
7269 if (!m_targets.GetItemTarget())
7271
7274 }
7275 // if not item target then required item must be equipped
7276 else
7277 {
7278 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7279 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7282 }
7283
7284 // do not take reagents for these item casts
7286 {
7288 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7289 if (!checkReagents)
7290 if (Item* targetItem = m_targets.GetItemTarget())
7291 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7292 checkReagents = true;
7293
7294 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7295 if (checkReagents)
7296 {
7297 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7298 {
7299 if (m_spellInfo->Reagent[i] <= 0)
7300 continue;
7301
7302 uint32 itemid = m_spellInfo->Reagent[i];
7303 uint32 itemcount = m_spellInfo->ReagentCount[i];
7304
7305 // if CastItem is also spell reagent
7306 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7307 {
7308 ItemTemplate const* proto = m_CastItem->GetTemplate();
7309 if (!proto)
7311 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7312 {
7313 // CastItem will be used up and does not count as reagent
7314 int32 charges = m_CastItem->GetSpellCharges(s);
7315 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7316 {
7317 ++itemcount;
7318 break;
7319 }
7320 }
7321 }
7322 if (!player->HasItemCount(itemid, itemcount))
7323 return SPELL_FAILED_REAGENTS;
7324 }
7325 }
7326
7327 // check totem-item requirements (items presence in inventory)
7328 uint32 totems = 2;
7329 for (int i = 0; i < 2; ++i)
7330 {
7331 if (m_spellInfo->Totem[i] != 0)
7332 {
7333 if (player->HasItemCount(m_spellInfo->Totem[i]))
7334 {
7335 totems -= 1;
7336 continue;
7337 }
7338 }
7339 else
7340 totems -= 1;
7341 }
7342 if (totems != 0)
7343 return SPELL_FAILED_TOTEMS; //0x7C
7344
7345 // Check items for TotemCategory (items presence in inventory)
7347 for (int i = 0; i < 2; ++i)
7348 {
7349 if (m_spellInfo->TotemCategory[i] != 0)
7350 {
7352 {
7353 TotemCategory -= 1;
7354 continue;
7355 }
7356 }
7357 else
7358 TotemCategory -= 1;
7359 }
7360 if (TotemCategory != 0)
7361 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7362 }
7363
7364 // special checks for spell effects
7365 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7366 {
7367 switch (m_spellInfo->Effects[i].Effect)
7368 {
7371 {
7372 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7373 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7374 if (target->IsPlayer() && !IsTriggered())
7375 {
7376 // SPELL_EFFECT_CREATE_ITEM_2 differs from SPELL_EFFECT_CREATE_ITEM in that it picks the random item to create from a pool of potential items,
7377 // so we need to make sure there is at least one free space in the player's inventory
7379 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7380 {
7381 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7383 }
7384
7385 if (m_spellInfo->Effects[i].ItemType)
7386 {
7387 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7388 if (!itemTemplate)
7390
7391 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7392 ItemPosCountVec dest;
7393 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7394 if (msg != EQUIP_ERR_OK)
7395 {
7397 if (!itemTemplate->ItemLimitCategory)
7398 {
7399 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7401 }
7402 else
7403 {
7404 // Conjure Food/Water/Refreshment spells
7407 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7408 {
7409 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7411 }
7412 else
7413 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7414
7416 }
7417 }
7418 }
7419 }
7420 break;
7421 }
7423 {
7424 if (player->GetFreeInventorySpace() == 0)
7425 {
7426 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7428 }
7429 break;
7430 }
7432 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7434 {
7435 // cannot enchant vellum for other player
7438 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7441 ItemPosCountVec dest;
7442 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7443 if (msg != EQUIP_ERR_OK)
7444 {
7445 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7447 }
7448 }
7449 [[fallthrough]];
7451 {
7452 Item* targetItem = m_targets.GetItemTarget();
7453 if (!targetItem)
7455
7456 // xinef: required level has to be checked also! Exploit fix
7457 if (targetItem->GetTemplate()->ItemLevel < m_spellInfo->BaseLevel || (targetItem->GetTemplate()->RequiredLevel && targetItem->GetTemplate()->RequiredLevel < m_spellInfo->BaseLevel))
7458 return SPELL_FAILED_LOWLEVEL;
7459
7460 bool isItemUsable = false;
7461 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7462 {
7463 ItemTemplate const* proto = targetItem->GetTemplate();
7464 if (proto->Spells[e].SpellId && (
7467 {
7468 isItemUsable = true;
7469 break;
7470 }
7471 }
7472
7473 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7474 // do not allow adding usable enchantments to items that have use effect already
7475 if (enchantEntry)
7476 {
7477 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7478 {
7479 switch (enchantEntry->type[s])
7480 {
7482 if (isItemUsable)
7484 break;
7486 {
7487 uint32 numSockets = 0;
7488 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7489 if (targetItem->GetTemplate()->Socket[socket].Color)
7490 ++numSockets;
7491
7492 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7494 break;
7495 }
7496 }
7497 }
7498 }
7499
7500 // Not allow enchant in trade slot for some enchant type
7501 if (targetItem->GetOwner() != m_caster)
7502 {
7503 if (!enchantEntry)
7504 return SPELL_FAILED_ERROR;
7505 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7507 }
7508 break;
7509 }
7511 {
7512 Item* item = m_targets.GetItemTarget();
7513 if (!item)
7515 // Not allow enchant in trade slot for some enchant type
7516 if (item->GetOwner() != m_caster)
7517 {
7518 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7519 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7520 if (!pEnchant)
7521 return SPELL_FAILED_ERROR;
7522 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7524 }
7525
7526 // Xinef: Apply item level restriction if the enchanting spell has max level restrition set
7527 if (m_CastItem && m_spellInfo->MaxLevel > 0)
7528 {
7530 return SPELL_FAILED_LOWLEVEL;
7531 if (item->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7533 }
7534
7535 break;
7536 }
7538 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7539 break;
7541 {
7542 if (!m_targets.GetItemTarget())
7544
7545 // prevent disenchanting in trade slot
7548
7549 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7550 if (!itemProto)
7552
7553 uint32 item_quality = itemProto->Quality;
7554 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7555 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7556 if (item_disenchantskilllevel == uint32(-1))
7558 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7560 if (item_quality > 4 || item_quality < 2)
7562 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7564 if (!itemProto->DisenchantID)
7566 break;
7567 }
7569 {
7570 if (!m_targets.GetItemTarget())
7572 //ensure item is a prospectable ore
7575 //prevent prospecting in trade slot
7578 //Check for enough skill in jewelcrafting
7579 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7580 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7582 //make sure the player has the required ores in inventory
7583 if (m_targets.GetItemTarget()->GetCount() < 5)
7585
7588
7589 break;
7590 }
7592 {
7593 if (!m_targets.GetItemTarget())
7595 //ensure item is a millable herb
7598 //prevent milling in trade slot
7601 //Check for enough skill in inscription
7602 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7603 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7605 //make sure the player has the required herbs in inventory
7606 if (m_targets.GetItemTarget()->GetCount() < 5)
7608
7611
7612 break;
7613 }
7616 {
7617 if (!m_caster->IsPlayer())
7619
7621 break;
7622
7624 if (!pItem || pItem->IsBroken())
7626
7627 switch (pItem->GetTemplate()->SubClass)
7628 {
7630 {
7631 uint32 ammo = pItem->GetEntry();
7632 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7633 return SPELL_FAILED_NO_AMMO;
7634 };
7635 break;
7639 {
7641 if (!ammo)
7642 {
7643 // Requires No Ammo
7644 if (m_caster->HasAura(46699))
7645 break; // skip other checks
7646
7647 return SPELL_FAILED_NO_AMMO;
7648 }
7649
7650 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7651 if (!ammoProto)
7652 return SPELL_FAILED_NO_AMMO;
7653
7654 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7655 return SPELL_FAILED_NO_AMMO;
7656
7657 // check ammo ws. weapon compatibility
7658 switch (pItem->GetTemplate()->SubClass)
7659 {
7662 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7663 return SPELL_FAILED_NO_AMMO;
7664 break;
7666 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7667 return SPELL_FAILED_NO_AMMO;
7668 break;
7669 default:
7670 return SPELL_FAILED_NO_AMMO;
7671 }
7672
7673 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7674 {
7676 return SPELL_FAILED_NO_AMMO;
7677 }
7678 };
7679 break;
7681 break;
7682 default:
7683 break;
7684 }
7685 break;
7686 }
7688 {
7689 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7690 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7691
7692 if (!pProto)
7694
7695 if (Item* pitem = player->GetItemByEntry(item_id))
7696 {
7697 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7698 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7700 }
7701 break;
7702 }
7703 default:
7704 break;
7705 }
7706 }
7707
7708 // check weapon presence in slots for main/offhand weapons
7709 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7710 {
7711 // main hand weapon required
7713 {
7715
7716 // skip spell if no weapon in slot or broken
7717 if (!item || item->IsBroken())
7719
7720 // skip spell if weapon not fit to triggered spell
7723 }
7724
7725 // offhand hand weapon required
7727 {
7729
7730 // skip spell if no weapon in slot or broken
7731 if (!item || item->IsBroken())
7733
7734 // skip spell if weapon not fit to triggered spell
7737 }
7738
7740 }
7741
7742 return SPELL_CAST_OK;
7743}
std::int8_t int8
Definition: Define.h:105
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
@ PLAYER_AMMO_ID
Definition: UpdateFields.h:369
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:771
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition: ItemTemplate.h:362
@ ITEM_SUBCLASS_WEAPON_GUN
Definition: ItemTemplate.h:347
@ ITEM_SUBCLASS_WEAPON_BOW
Definition: ItemTemplate.h:346
@ ITEM_SUBCLASS_WEAPON_WAND
Definition: ItemTemplate.h:363
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition: ItemTemplate.h:360
@ ITEM_SPELLTRIGGER_ON_USE
Definition: ItemTemplate.h:77
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition: ItemTemplate.h:87
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:176
@ ITEM_FLAG_NO_REAGENT_COST
Definition: ItemTemplate.h:175
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:165
@ ITEM_SUBCLASS_ARROW
Definition: ItemTemplate.h:416
@ ITEM_SUBCLASS_BULLET
Definition: ItemTemplate.h:417
#define MAX_ITEM_PROTO_SOCKETS
Definition: ItemTemplate.h:614
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:615
@ ITEM_CLASS_PROJECTILE
Definition: ItemTemplate.h:297
@ ITEM_CLASS_ARMOR
Definition: ItemTemplate.h:295
@ ITEM_CLASS_WEAPON
Definition: ItemTemplate.h:293
@ ITEM_CLASS_CONSUMABLE
Definition: ItemTemplate.h:291
InventoryResult
Definition: Item.h:46
@ EQUIP_ERR_OK
Definition: Item.h:47
@ EQUIP_ERR_INVENTORY_FULL
Definition: Item.h:97
#define MAX_ITEM_SPELLS
Definition: Item.h:215
@ ENCHANTMENT_CAN_SOULBOUND
Definition: Item.h:201
@ NULL_BAG
Definition: Item.h:40
@ NULL_SLOT
Definition: Item.h:41
@ PRISMATIC_ENCHANTMENT_SLOT
Definition: Item.h:175
@ EFFECT_1
Definition: SharedDefines.h:32
@ MAX_POWERS
Definition: SharedDefines.h:276
@ SPELL_EFFECT_DISENCHANT
Definition: SharedDefines.h:877
@ SPELL_EFFECT_PROSPECTING
Definition: SharedDefines.h:905
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition: SharedDefines.h:870
@ SPELL_EFFECT_ENCHANT_ITEM
Definition: SharedDefines.h:831
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition: SharedDefines.h:836
@ SPELL_EFFECT_HEAL
Definition: SharedDefines.h:788
@ SPELL_EFFECT_MILLING
Definition: SharedDefines.h:936
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition: SharedDefines.h:844
@ SPELL_EFFECT_CREATE_ITEM_2
Definition: SharedDefines.h:935
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition: SharedDefines.h:795
@ SPELL_EFFECT_ENERGIZE
Definition: SharedDefines.h:808
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition: SharedDefines.h:837
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition: SharedDefines.h:934
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition: SharedDefines.h:832
@ SPELL_EFFECT_CREATE_ITEM
Definition: SharedDefines.h:802
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition: SharedDefines.h:503
@ SPELLFAMILY_MAGE
Definition: SharedDefines.h:3531
TotemCategory
Definition: SharedDefines.h:3083
@ SPELL_FAILED_CANT_BE_MILLED
Definition: SharedDefines.h:965
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition: SharedDefines.h:980
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition: SharedDefines.h:978
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition: SharedDefines.h:1128
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition: SharedDefines.h:1071
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition: SharedDefines.h:953
@ SPELL_FAILED_NOT_TRADEABLE
Definition: SharedDefines.h:1019
@ SPELL_FAILED_ITEM_NOT_READY
Definition: SharedDefines.h:994
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition: SharedDefines.h:1025
@ SPELL_FAILED_ITEM_GONE
Definition: SharedDefines.h:992
@ SPELL_FAILED_NO_AMMO
Definition: SharedDefines.h:1024
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition: SharedDefines.h:993
@ SPELL_FAILED_EQUIPPED_ITEM
Definition: SharedDefines.h:977
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition: SharedDefines.h:951
@ SPELL_FAILED_ON_USE_ENCHANT
Definition: SharedDefines.h:1119
@ SPELL_FAILED_TOTEMS
Definition: SharedDefines.h:1080
@ SPELL_FAILED_ERROR
Definition: SharedDefines.h:981
@ SPELL_FAILED_REAGENTS
Definition: SharedDefines.h:1049
@ SPELL_FAILED_MAX_SOCKETS
Definition: SharedDefines.h:1133
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition: SharedDefines.h:963
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition: SharedDefines.h:1078
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition: SharedDefines.h:1004
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition: SharedDefines.h:966
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition: SharedDefines.h:979
@ SPELL_FAILED_TOTEM_CATEGORY
Definition: SharedDefines.h:1079
@ SKILL_INSCRIPTION
Definition: SharedDefines.h:3002
@ SKILL_ENCHANTING
Definition: SharedDefines.h:2954
@ SKILL_JEWELCRAFTING
Definition: SharedDefines.h:2985
#define MAX_SPELL_REAGENTS
Definition: DBCStructure.h:1638
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1837
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition: DBCEnums.h:373
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition: DBCEnums.h:374
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:304
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:317
bool IsBroken() const
Definition: Item.h:257
bool IsWeaponVellum() const
Definition: Item.h:338
bool IsArmorVellum() const
Definition: Item.h:339
Player * GetOwner() const
Definition: Item.cpp:550
ObjectGuid GetOwnerGUID() const
Definition: Item.h:231
uint32 GetCount() const
Definition: Item.h:272
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition: Item.cpp:885
int32 SpellCharges
Definition: ItemTemplate.h:593
uint32 SpellTrigger
Definition: ItemTemplate.h:592
int32 SpellId
Definition: ItemTemplate.h:591
uint32 Color
Definition: ItemTemplate.h:602
Definition: ItemTemplate.h:619
uint32 DisenchantID
Definition: ItemTemplate.h:690
uint32 Quality
Definition: ItemTemplate.h:626
uint32 RequiredSkillRank
Definition: ItemTemplate.h:638
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:729
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition: ItemTemplate.h:662
uint32 RequiredDisenchantSkill
Definition: ItemTemplate.h:684
uint32 RequiredLevel
Definition: ItemTemplate.h:636
bool HasFlag(ItemFlags flag) const
Definition: ItemTemplate.h:827
uint32 Class
Definition: ItemTemplate.h:621
uint32 ItemLimitCategory
Definition: ItemTemplate.h:687
uint32 SubClass
Definition: ItemTemplate.h:622
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition: ItemTemplate.h:681
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:305
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition: Player.cpp:12517
uint32 GetFreeInventorySpace() const
Definition: PlayerStorage.cpp:468
Item * GetItemByEntry(uint32 entry) const
Definition: PlayerStorage.cpp:3371
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition: PlayerStorage.cpp:657
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition: PlayerStorage.cpp:853
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition: Player.cpp:12562
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition: PlayerStorage.cpp:4023
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition: Player.h:1274
bool CanUseAttackType(uint8 attacktype) const
Definition: Unit.h:1066
bool IsFullHealth() const
Definition: Unit.h:872
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:892
void SetUInt32Value(uint16 index, uint32 value)
Definition: Unit.cpp:21281
uint32 GetPower(Powers power) const
Definition: Unit.h:891
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:224
uint32 GetItemTargetEntry() const
Definition: Spell.h:140
ObjectGuid m_castItemGUID
Definition: Spell.h:523
uint32 BaseLevel
Definition: SpellInfo.h:359
uint32 MaxLevel
Definition: SpellInfo.h:358
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition: SpellInfo.h:373
flag96 SpellFamilyFlags
Definition: SpellInfo.h:388
std::array< uint32, 2 > TotemCategory
Definition: SpellInfo.h:378
int32 EquippedItemClass
Definition: SpellInfo.h:375
std::array< uint32, 2 > Totem
Definition: SpellInfo.h:372
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition: SpellInfo.h:374
Definition: DBCStructure.h:1840
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1843
uint32 slot
Definition: DBCStructure.h:1850

References BASE_ATTACK, SpellInfo::BaseLevel, Player::CanNoReagentCast(), Player::CanStoreNewItem(), Unit::CanUseAttackType(), Unit::CastSpell(), ItemTemplate::Class, _Socket::Color, ItemTemplate::DisenchantID, SpellInfo::DmgClass, EFFECT_1, SpellInfo::Effects, ENCHANTMENT_CAN_SOULBOUND, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, SpellInfo::EquippedItemClass, Item::GetCount(), Item::GetEnchantmentId(), Object::GetEntry(), Player::GetFreeInventorySpace(), Object::GetGUID(), Player::GetItemByEntry(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetEntry(), SpellCastTargets::GetItemTargetGUID(), Unit::GetMaxPower(), ItemTemplate::GetMaxStackSize(), Item::GetOwner(), Item::GetOwnerGUID(), Unit::GetPower(), Player::GetSkillValue(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetUInt32Value(), SpellCastTargets::GetUnitTarget(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), ItemTemplate::HasFlag(), Player::HasItemCount(), Player::HasItemFitToSpellRequirements(), Player::HasItemTotemCategory(), HasTriggeredCastFlag(), LootStore::HaveLootFor(), Item::IsArmorVellum(), Item::IsBroken(), Item::IsFitToSpellRequirements(), Unit::IsFullHealth(), Object::IsPlayer(), IsTriggered(), Item::IsWeaponVellum(), ITEM_CLASS_ARMOR, ITEM_CLASS_CONSUMABLE, ITEM_CLASS_PROJECTILE, ITEM_CLASS_WEAPON, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, ITEM_ENCHANTMENT_TYPE_USE_SPELL, ITEM_FLAG_IS_MILLABLE, ITEM_FLAG_IS_PROSPECTABLE, ITEM_FLAG_NO_REAGENT_COST, ITEM_SPELLTRIGGER_ON_NO_DELAY_USE, ITEM_SPELLTRIGGER_ON_USE, ITEM_SUBCLASS_ARROW, ITEM_SUBCLASS_BULLET, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, ITEM_SUBCLASS_WEAPON_WAND, ItemTemplate::ItemLevel, ItemTemplate::ItemLimitCategory, LootTemplates_Milling, LootTemplates_Prospecting, m_attackType, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, m_weaponItem, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, MAX_ITEM_SPELLS, MAX_POWERS, MAX_SPELL_EFFECTS, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::MaxLevel, NULL_BAG, NULL_SLOT, OFF_ATTACK, PLAYER_AMMO_ID, PRISMATIC_ENCHANTMENT_SLOT, ItemTemplate::Quality, RANGED_ATTACK, SpellInfo::Reagent, SpellInfo::ReagentCount, ItemTemplate::RequiredDisenchantSkill, ItemTemplate::RequiredLevel, ItemTemplate::RequiredSkillRank, Player::SendEquipError(), Unit::SetUInt32Value(), SKILL_ENCHANTING, SKILL_INSCRIPTION, SKILL_JEWELCRAFTING, SpellItemEnchantmentEntry::slot, sObjectMgr, ItemTemplate::Socket, SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_CREATE_ITEM_2, SPELL_EFFECT_CREATE_MANA_GEM, SPELL_EFFECT_CREATE_RANDOM_ITEM, SPELL_EFFECT_DISENCHANT, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_HEAL, SPELL_EFFECT_MILLING, SPELL_EFFECT_PROSPECTING, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_FAILED_ALREADY_AT_FULL_HEALTH, SPELL_FAILED_ALREADY_AT_FULL_POWER, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_DISENCHANTED, SPELL_FAILED_CANT_BE_MILLED, SPELL_FAILED_CANT_BE_PROSPECTED, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_EQUIPPED_ITEM, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_ERROR, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_AT_MAX_CHARGES, SPELL_FAILED_ITEM_GONE, SPELL_FAILED_ITEM_NOT_FOUND, SPELL_FAILED_ITEM_NOT_READY, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MAX_SOCKETS, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_NO_AMMO, SPELL_FAILED_NO_CHARGES_REMAIN, SPELL_FAILED_NOT_TRADEABLE, SPELL_FAILED_ON_USE_ENCHANT, SPELL_FAILED_REAGENTS, SPELL_FAILED_TARGET_NOT_PLAYER, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, _Spell::SpellCharges, SPELLFAMILY_MAGE, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, _Spell::SpellId, ItemTemplate::Spells, _Spell::SpellTrigger, sSpellItemEnchantmentStore, ItemTemplate::SubClass, TARGET_UNIT_PET, Object::ToPlayer(), SpellInfo::Totem, SpellInfo::TotemCategory, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, and SpellItemEnchantmentEntry::type.

Referenced by CheckCast().

◆ CheckPetCast()

SpellCastResult Spell::CheckPetCast ( Unit target)
6814{
6815 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6817
6818 // dead owner (pets still alive when owners ressed?)
6819 if (Unit* owner = m_caster->GetCharmerOrOwner())
6820 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6822
6823 if (!target && m_targets.GetUnitTarget())
6824 target = m_targets.GetUnitTarget();
6825
6827 {
6828 if (!target)
6830 m_targets.SetUnitTarget(target);
6831 }
6832
6833 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6835
6836 // cooldown
6837 if (Creature const* creatureCaster = m_caster->ToCreature())
6838 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6840
6841 // Check if spell is affected by GCD
6845
6846 return CheckCast(true);
6847}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition: CharmInfo.cpp:404
void SetUnitTarget(Unit *target)
Definition: Spell.cpp:240
int32 CalcPowerCost(Unit const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2400
uint32 StartRecoveryCategory
Definition: SpellInfo.h:350

References SpellInfo::CalcPowerCost(), CheckCast(), Unit::GetCharmerOrOwner(), Unit::GetCharmInfo(), Object::GetEntry(), CharmInfo::GetGlobalCooldownMgr(), SpellCastTargets::GetUnitTarget(), GlobalCooldownMgr::HasGlobalCooldown(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, m_caster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_targets, SpellInfo::NeedsExplicitUnitTarget(), SpellCastTargets::SetUnitTarget(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_NOT_READY, SPELL_FAILED_SPELL_IN_PROGRESS, SpellInfo::StartRecoveryCategory, Object::ToCreature(), TRIGGERED_IGNORE_CAST_IN_PROGRESS, and UNIT_STATE_CASTING.

Referenced by CanAutoCast(), WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7133{
7134 // item cast not used power
7135 if (m_CastItem)
7136 return SPELL_CAST_OK;
7137
7138 //While .cheat power is enabled dont check if we need power to cast the spell
7139 if (m_caster->IsPlayer())
7140 {
7142 {
7143 return SPELL_CAST_OK;
7144 }
7145 }
7146
7147 // health as power used - need check health amount
7149 {
7152 return SPELL_CAST_OK;
7153 }
7154 // Check valid power type
7156 {
7157 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7158 return SPELL_FAILED_UNKNOWN;
7159 }
7160
7161 //check rune cost only if a spell has PowerType == POWER_RUNE
7163 {
7165 if (failReason != SPELL_CAST_OK)
7166 return failReason;
7167 }
7168
7169 // Check power amount
7172 return SPELL_FAILED_NO_POWER;
7173 else
7174 return SPELL_CAST_OK;
7175}
PowerType
Definition: VehicleDefines.h:29
@ CHEAT_POWER
Definition: Player.h:1002
@ POWER_HEALTH
Definition: SharedDefines.h:278
@ POWER_RUNE
Definition: SharedDefines.h:274
@ SPELL_FAILED_NO_POWER
Definition: SharedDefines.h:1034
@ SPELL_FAILED_UNKNOWN
Definition: SharedDefines.h:1136
uint32 GetHealth() const
Definition: Unit.h:869
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition: Spell.cpp:5407
uint32 RuneCostID
Definition: SpellInfo.h:368
uint32 PowerType
Definition: SpellInfo.h:362

References CHEAT_POWER, CheckRuneCost(), Player::GetCommandStatus(), Unit::GetHealth(), Unit::GetPower(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, MAX_POWERS, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, SPELL_CAST_OK, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_NO_POWER, SPELL_FAILED_UNKNOWN, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7047{
7048 // Don't check for instant cast spells
7049 if (!strict && m_casttime == 0)
7050 return SPELL_CAST_OK;
7051
7052 uint32 range_type = 0;
7053
7055 {
7056 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7057 // these are triggered by other spells - possibly we should omit range check in that case?
7058 if (m_spellInfo->RangeEntry->ID == 1)
7059 return SPELL_CAST_OK;
7060
7061 range_type = m_spellInfo->RangeEntry->Flags;
7062 }
7063
7064 Unit* target = m_targets.GetUnitTarget();
7065 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7066 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7067
7068 // xinef: hack for npc shooters
7069 if (min_range && GetCaster()->IsCreature() && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7070 range_type = SPELL_RANGE_RANGED;
7071
7072 if (Player* modOwner = m_caster->GetSpellModOwner())
7073 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7074
7075 // xinef: dont check max_range to strictly after cast
7076 if (range_type != SPELL_RANGE_MELEE && !strict)
7077 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7078
7079 if (target)
7080 {
7081 if (target != m_caster)
7082 {
7083 // Xinef: Spells with 5yd range can hit target 9yd away?
7084 if (range_type == SPELL_RANGE_MELEE)
7085 {
7086 float real_max_range = max_range;
7087 if (!m_caster->IsCreature() && m_caster->isMoving() && target->isMoving() && !m_caster->IsWalking() && !target->IsWalking())
7088 real_max_range -= MIN_MELEE_REACH; // Because of lag, we can not check too strictly here (is only used if both caster and target are moving)
7089 else
7090 real_max_range -= 2 * MIN_MELEE_REACH;
7091
7092 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7094 }
7095 else if (!m_caster->IsWithinCombatRange(target, max_range))
7096 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7097
7099 {
7100 if (m_caster->IsWithinMeleeRange(target))
7102 }
7103
7104 if (m_caster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target))
7106 }
7107
7108 // Xinef: check min range for self casts
7109 if (min_range && range_type != SPELL_RANGE_RANGED && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
7111 }
7112
7113 if (GameObject* goTarget = m_targets.GetGOTarget())
7114 {
7115 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7116 {
7118 }
7119 }
7120
7121 if (m_targets.HasDst() && !m_targets.HasTraj())
7122 {
7123 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7125 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7127 }
7128
7129 return SPELL_CAST_OK;
7130}
#define MIN_MELEE_REACH
Definition: ObjectDefines.h:47
@ SPELLMOD_RANGE
Definition: SpellDefines.h:82
@ SPELL_FACING_FLAG_INFRONT
Definition: SpellDefines.h:126
@ SPELL_RANGE_MELEE
Definition: Spell.h:89
@ SPELL_RANGE_RANGED
Definition: Spell.h:90
@ SPELL_FAILED_TOO_CLOSE
Definition: SharedDefines.h:1077
@ SPELL_FAILED_OUT_OF_RANGE
Definition: SharedDefines.h:1046
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition: Object.cpp:1295
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition: Position.cpp:140
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition: Unit.cpp:648
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15121
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition: Unit.cpp:664
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15101
bool IsWalking() const
Definition: Unit.h:1709
Unit * GetCaster() const
Definition: Spell.h:573
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:369
uint32 FacingCasterFlags
Definition: SpellInfo.h:338
uint32 Flags
Definition: DBCStructure.h:1796
uint32 ID
Definition: DBCStructure.h:1793

References SpellInfo::DmgClass, SpellInfo::FacingCasterFlags, SpellRangeEntry::Flags, GetCaster(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetGOTarget(), Unit::GetSpellMaxRangeForTarget(), Unit::GetSpellMinRangeForTarget(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::HasDst(), Position::HasInArc(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellRangeEntry::ID, Object::IsCreature(), Unit::isMoving(), Object::IsPlayer(), Unit::IsWalking(), Unit::IsWithinCombatRange(), WorldObject::IsWithinDist3d(), Unit::IsWithinMeleeRange(), m_caster, m_casttime, m_spellInfo, m_targets, MIN_MELEE_REACH, SpellInfo::RangeEntry, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_RANGED, SPELL_FACING_FLAG_INFRONT, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_TOO_CLOSE, SPELL_FAILED_UNIT_NOT_INFRONT, SPELL_RANGE_MELEE, SPELL_RANGE_RANGED, SPELLMOD_RANGE, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5408{
5409 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5410 return SPELL_CAST_OK;
5411
5412 if (!m_caster->IsPlayer())
5413 return SPELL_CAST_OK;
5414
5415 Player* player = m_caster->ToPlayer();
5416 //If we are in .cheat power mode we dont need to check the cost as we are expected to be able to use it anyways (infinite power)
5417 if (player->GetCommandStatus(CHEAT_POWER))
5418 {
5419 return SPELL_CAST_OK;
5420 }
5421
5423 return SPELL_CAST_OK;
5424
5425 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5426
5427 if (!src)
5428 return SPELL_CAST_OK;
5429
5430 if (src->NoRuneCost())
5431 return SPELL_CAST_OK;
5432
5433 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5434
5435 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5436 {
5437 runeCost[i] = src->RuneCost[i];
5438 if (Player* modOwner = m_caster->GetSpellModOwner())
5439 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5440 }
5441
5442 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5443
5444 for (uint32 i = 0; i < MAX_RUNES; ++i)
5445 {
5446 RuneType rune = player->GetCurrentRune(i);
5447 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5448 runeCost[rune]--;
5449 }
5450
5451 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5452 if (runeCost[i] > 0)
5453 runeCost[RUNE_DEATH] += runeCost[i];
5454
5455 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5456 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5457
5458 return SPELL_CAST_OK;
5459}
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
@ CLASS_CONTEXT_ABILITY
Definition: UnitDefines.h:213
RuneType
Definition: Player.h:408
@ RUNE_DEATH
Definition: Player.h:412
@ NUM_RUNE_TYPES
Definition: Player.h:413
#define MAX_RUNES
Definition: Player.h:398
@ SPELLMOD_COST
Definition: SpellDefines.h:91
@ CLASS_DEATH_KNIGHT
Definition: SharedDefines.h:146
uint32 GetRuneCooldown(uint8 index) const
Definition: Player.h:2490
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition: Player.cpp:1280
RuneType GetCurrentRune(uint8 index) const
Definition: Player.h:2489
Definition: DBCStructure.h:1804
uint32 RuneCost[3]
Definition: DBCStructure.h:1806
bool NoRuneCost() const
Definition: DBCStructure.h:1809

References CHEAT_POWER, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetCommandStatus(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_RUNES, SpellRuneCostEntry::NoRuneCost(), NUM_RUNE_TYPES, POWER_RUNE, SpellInfo::PowerType, RUNE_DEATH, SpellRuneCostEntry::RuneCost, SPELL_CAST_OK, SPELL_FAILED_NO_POWER, SPELLMOD_COST, sSpellRuneCostStore, and Object::ToPlayer().

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
8711{
8712 // Skip if there are not any script
8713 if (!m_loadedScripts.size())
8714 return true;
8715
8716 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8717 {
8718 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8719 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8720 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8721 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8722 return false;
8723
8724 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8725 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8726 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8727 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8728 return false;
8729 }
8730 return true;
8731}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7746{
7747 // check spell focus object
7749 {
7751 Cell cell(p);
7752
7753 GameObject* ok = nullptr;
7756
7758 Map& map = *m_caster->GetMap();
7759 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7760
7761 if (!ok)
7763
7764 focusObject = ok; // game object found in range
7765 }
7766 return SPELL_CAST_OK;
7767}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition: SharedDefines.h:1051
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:191
Definition: TypeContainer.h:101
Definition: TypeContainerVisitor.h:84
Definition: Cell.h:46
Definition: GridNotifiers.h:319
Definition: GridNotifiers.h:657
Definition: Map.h:313
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition: Map.h:873
uint32 RequiresSpellFocus
Definition: SpellInfo.h:337

References Acore::ComputeCellCoord(), focusObject, WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetVisibilityRange(), m_caster, m_spellInfo, SpellInfo::RequiresSpellFocus, SPELL_CAST_OK, SPELL_FAILED_REQUIRES_SPELL_FOCUS, and Cell::Visit().

Referenced by CheckCast().

◆ CheckSrc()

void Spell::CheckSrc ( )
inline
bool HasSrc() const
Definition: Spell.h:164
void SetSrc(float x, float y, float z)
Definition: Spell.cpp:368

References SpellCastTargets::HasSrc(), m_caster, m_targets, and SpellCastTargets::SetSrc().

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2373{
2374 m_UniqueTargetInfo.clear();
2375 m_UniqueGOTargetInfo.clear();
2376 m_UniqueItemInfo.clear();
2377 m_delayMoment = 0;
2379}
uint64 m_delayTrajectory
Definition: Spell.h:640

References m_delayMoment, m_delayTrajectory, m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

Referenced by spell_dk_raise_dead::CheckCast(), and Spell().

◆ Delayed()

void Spell::Delayed ( )
7770{
7771 if (!m_caster)// || !m_caster->IsPlayer())
7772 return;
7773
7774 //if (m_spellState == SPELL_STATE_DELAYED)
7775 // return; // spell is active and can't be time-backed
7776
7777 if (isDelayableNoMore()) // Spells may only be delayed twice
7778 return;
7779
7781 return;
7782
7783 // spells not loosing casting time (slam, dynamites, bombs..)
7784 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7785 // return;
7786
7787 //check pushback reduce
7788 int32 delaytime = 500; // spellcasting delay is normally 500ms
7789 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7792 if (delayReduce >= 100)
7793 return;
7794
7795 AddPct(delaytime, -delayReduce);
7796
7797 if (m_timer + delaytime > m_casttime)
7798 {
7799 delaytime = m_casttime - m_timer;
7801 }
7802 else
7803 m_timer += delaytime;
7804
7805 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7806
7807 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7808 data << m_caster->GetPackGUID();
7809 data << uint32(delaytime);
7810
7811 m_caster->SendMessageToSet(&data, true);
7812}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:168
T AddPct(T &base, U pct)
Definition: Util.h:67
@ SPELL_AURA_REDUCE_PUSHBACK
Definition: SpellAuraDefines.h:212
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition: SpellDefines.h:86
@ SPELL_ATTR6_NO_PUSHBACK
Definition: SharedDefines.h:619
@ SMSG_SPELL_DELAYED
Definition: Opcodes.h:512
PackedGuid const & GetPackGUID() const
Definition: Object.h:111
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.cpp:2080
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition: Player.cpp:9729
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:5880
Definition: WorldPacket.h:27
bool isDelayableNoMore()
Definition: Spell.h:628

References AddPct(), Player::ApplySpellMod(), Object::GetPackGUID(), Unit::GetTotalAuraModifier(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_timer, WorldObject::SendMessageToSet(), SMSG_SPELL_DELAYED, SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DelayedChannel()

void Spell::DelayedChannel ( )
7815{
7817 return;
7818
7819 if (isDelayableNoMore()) // Spells may only be delayed twice
7820 return;
7821
7823 return;
7824
7825 //check pushback reduce
7826 // should be affected by modifiers, not take the dbc duration.
7828
7829 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7830 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7833 if (delayReduce >= 100)
7834 return;
7835
7836 AddPct(delaytime, -delayReduce);
7837
7838 if (m_timer <= delaytime)
7839 {
7840 delaytime = m_timer;
7841 m_timer = 0;
7842 }
7843 else
7844 m_timer -= delaytime;
7845
7846 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7847
7848 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7849 if ((*ihit).missCondition == SPELL_MISS_NONE)
7850 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7851 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7852
7853 // partially interrupt persistent area auras
7855 dynObj->Delay(delaytime);
7856
7858}
T CalculatePct(T base, U pct)
Definition: Util.h:61
Definition: DynamicObject.h:35
DynamicObject * GetDynObject(uint32 spellId)
Definition: Unit.cpp:6098
uint32 getState() const
Definition: Spell.h:482
int32 GetDuration() const
Definition: SpellInfo.cpp:2337

References AddPct(), Player::ApplySpellMod(), CalculatePct(), SpellInfo::GetDuration(), Unit::GetDynObject(), Object::GetGUID(), getState(), Unit::GetTotalAuraModifier(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), Object::IsPlayer(), LOG_DEBUG, m_caster, m_channeledDuration, m_originalCasterGUID, m_spellInfo, m_timer, m_UniqueTargetInfo, SendChannelUpdate(), SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DoAllEffectOnLaunchTarget()

void Spell::DoAllEffectOnLaunchTarget ( TargetInfo targetInfo,
float *  multiplier 
)
protected
8298{
8299 Unit* unit = nullptr;
8300 // In case spell hit target, do all effect on that target
8301 if (targetInfo.missCondition == SPELL_MISS_NONE)
8302 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8303 // In case spell reflect from target, do all effect on caster (if hit)
8304 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8305 unit = m_caster;
8306 if (!unit)
8307 return;
8308
8309 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8310 {
8311 if (targetInfo.effectMask & (1 << i))
8312 {
8313 m_damage = 0;
8314 m_healing = 0;
8315
8316 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8317
8318 if (m_damage > 0)
8319 {
8320 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8321 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8322 {
8324 if (m_caster->IsPlayer())
8325 {
8326 uint32 targetAmount = m_UniqueTargetInfo.size();
8327 if (targetAmount > 10)
8328 m_damage = m_damage * 10 / targetAmount;
8329 }
8330 }
8331 }
8332
8333 if (m_applyMultiplierMask & (1 << i))
8334 {
8336 m_damageMultipliers[i] *= multiplier[i];
8337 }
8338 targetInfo.damage += m_damage;
8339 }
8340 }
8341
8342 // xinef: totem's inherit owner crit chance and dancing rune weapon
8343 Unit* caster = m_caster;
8344 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8345 {
8346 if (Unit* owner = m_caster->GetOwner())
8347 caster = owner;
8348 }
8349 else if (m_originalCaster)
8350 caster = m_originalCaster;
8351
8352 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8353 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8354 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8355}
bool roll_chance_f(float chance)
Definition: Random.h:53
float SpellTakenCritChance(Unit const *caster, SpellInfo const *spellProto, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:12025
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:11950
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, Unit *caster) const
Definition: Unit.cpp:20359
uint32 SchoolMask
Definition: SpellInfo.h:392

References Unit::CalculateAOEDamageReduction(), TargetInfo::crit, TargetInfo::damage, SpellInfo::DmgClass, TargetInfo::effectMask, SpellInfo::Effects, Object::GetEntry(), Object::GetGUID(), Unit::GetOwner(), ObjectAccessor::GetUnit(), HandleEffects(), Object::IsPlayer(), Unit::IsTotem(), m_applyMultiplierMask, m_attackType, m_caster, m_damage, m_damageMultipliers, m_healing, m_originalCaster, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::reflectResult, roll_chance_f(), SpellInfo::SchoolMask, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_MISS_NONE, SPELL_MISS_REFLECT, Unit::SpellDoneCritChance(), Unit::SpellTakenCritChance(), and TargetInfo::targetGUID.

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3342{
3343 if (target->processed) // Check target
3344 return;
3345 target->processed = true; // Target checked in apply effects procedure
3346
3347 uint32 effectMask = target->effectMask;
3348 if (!effectMask)
3349 return;
3350
3351 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3352 if (!go)
3353 return;
3354
3357
3358 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3359 if (effectMask & (1 << effectNumber))
3360 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3361
3362 // xinef: inform ai about spellhit
3364
3366
3368}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: GameObjectAI.h:67
GameObjectAI * AI() const
Definition: GameObject.h:307
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition: Spell.cpp:8629
void CallScriptOnHitHandlers()
Definition: Spell.cpp:8642
void CallScriptAfterHitHandlers()
Definition: Spell.cpp:8655

References GameObject::AI(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::GOTargetInfo::effectMask, Map::GetGameObject(), WorldObject::GetMap(), HandleEffects(), m_caster, m_spellInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), Spell::GOTargetInfo::processed, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_MISS_NONE, GameObjectAI::SpellHit(), and Spell::GOTargetInfo::targetGUID.

◆ DoAllEffectOnTarget() [2/3]

void Spell::DoAllEffectOnTarget ( ItemTargetInfo target)
protected
3371{
3372 uint32 effectMask = target->effectMask;
3373 if (!target->item || !effectMask)
3374 return;
3375
3378
3379 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3380 if (effectMask & (1 << effectNumber))
3381 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3382
3384
3386}

References CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::ItemTargetInfo::effectMask, HandleEffects(), Spell::ItemTargetInfo::item, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), SPELL_EFFECT_HANDLE_HIT_TARGET, and SPELL_MISS_NONE.

◆ DoAllEffectOnTarget() [3/3]

void Spell::DoAllEffectOnTarget ( TargetInfo target)
protected
Todo:
: check how broad this rule should be
2611{
2612 if (!target || target->processed)
2613 return;
2614
2615 target->processed = true; // Target checked in apply effects procedure
2616
2617 // Get mask of effects for target
2618 uint8 mask = target->effectMask;
2619
2620 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2621 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2622 return;
2623
2624 if (!effectUnit || m_spellInfo->Id == 45927)
2625 {
2626 uint8 farMask = 0;
2627 // create far target mask
2628 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2629 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2630 if ((1 << i) & mask)
2631 farMask |= (1 << i);
2632
2633 if (!farMask)
2634 return;
2635 // find unit in world
2636 // Xinef: FindUnit Access without Map check!!! Intended
2637 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2638 if (!effectUnit)
2639 return;
2640
2641 // do far effects on the unit
2642 // can't use default call because of threading, do stuff as fast as possible
2643 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2644 if (farMask & (1 << i))
2645 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2646 return;
2647 }
2648
2649 if (effectUnit->IsAlive() != target->alive)
2650 return;
2651
2652 // Xinef: absorb delayed projectiles for 500ms
2654 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime && GameTime::GetGameTimeMS().count() < (effectUnit->m_lastSanctuaryTime + 500) &&
2655 effectUnit->FindMap() && !effectUnit->FindMap()->IsDungeon()
2656 )
2657 return; // No missinfo in that case
2658
2659 // Get original caster (if exist) and calculate damage/healing from him data
2661
2662 // Skip if m_originalCaster not avaiable
2663 if (!caster)
2664 return;
2665
2666 SpellMissInfo missInfo = target->missCondition;
2667
2668 // Need init unitTarget by default unit (can changed in code on reflect)
2669 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2670 unitTarget = effectUnit;
2671
2672 // Reset damage/healing counter
2673 m_damage = target->damage;
2674 m_healing = -target->damage;
2675
2676 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2677
2680
2681 //Spells with this flag cannot trigger if effect is casted on self
2683 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2684 Unit* spellHitTarget = nullptr;
2685
2686 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2687 spellHitTarget = unitTarget;
2688 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2689 {
2690 missInfo = target->reflectResult;
2691 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2692 {
2693 spellHitTarget = m_caster;
2695 if (m_caster->IsCreature())
2697 }
2698 }
2699
2700 if (spellHitTarget)
2701 {
2702 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2703 if (missInfo2 != SPELL_MISS_NONE)
2704 {
2705 if (missInfo2 != SPELL_MISS_MISS)
2706 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2707 m_damage = 0;
2708 spellHitTarget = nullptr;
2709
2710 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2711 if (missInfo2 == SPELL_MISS_EVADE)
2712 missInfo = SPELL_MISS_EVADE;
2713 }
2714 }
2715
2716 // Do not take combo points on dodge and miss
2717 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2718 {
2719 m_needComboPoints = false;
2720 // Restore spell mods for a miss/dodge/parry Cold Blood
2722 if (m_caster->IsPlayer() && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2723 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2724 }
2725
2726 // Fill base trigger info
2727 uint32 procAttacker = m_procAttacker;
2728 uint32 procVictim = m_procVictim;
2729 uint32 procEx = m_procEx;
2730
2731 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2732 if (canEffectTrigger && !procAttacker && !procVictim)
2733 {
2734 bool positive = true;
2735 if (m_damage > 0)
2736 positive = false;
2737 else if (!m_healing)
2738 {
2739 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2740 // If at least one effect negative spell is negative hit
2741 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2742 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2743 {
2744 positive = false;
2745 break;
2746 }
2747 }
2748 switch (m_spellInfo->DmgClass)
2749 {
2751 if (positive)
2752 {
2755 }
2756 else
2757 {
2760 }
2761 break;
2763 if (positive)
2764 {
2767 }
2768 else
2769 {
2772 }
2773 break;
2774 }
2775 }
2777
2778 // All calculated do it!
2779 // Do healing and triggers
2780 if (m_healing > 0)
2781 {
2782 bool crit = target->crit;
2783 uint32 addhealth = m_healing;
2784
2785 if (crit)
2786 {
2787 procEx |= PROC_EX_CRITICAL_HIT;
2788 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2789 }
2790 else
2791 procEx |= PROC_EX_NORMAL_HIT;
2792
2793 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2794
2795 // Xinef: override with forced crit, only visual result
2796 if (GetSpellValue()->ForcedCritResult)
2797 {
2798 crit = true;
2799 procEx |= PROC_EX_CRITICAL_HIT;
2800 }
2801
2802 int32 gain = caster->HealBySpell(healInfo, crit);
2803 unitTarget->getHostileRefMgr().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
2804 m_healing = gain;
2805
2806 // Xinef: if heal acutally healed something, add no overheal flag
2807 if (m_healing)
2808 procEx |= PROC_EX_NO_OVERHEAL;
2809
2810 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2811 if (canEffectTrigger)
2812 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2813 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2814 }
2815 // Do damage and triggers
2816 else if (m_damage > 0)
2817 {
2819
2820 // Fill base damage struct (unitTarget - is real spell target)
2822
2823 // Add bonuses and fill damageInfo struct
2824 // Dancing Rune Weapon...
2825 if (m_caster->GetEntry() == 27893)
2826 {
2827 if (Unit* owner = m_caster->GetOwner())
2828 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2829 }
2830 else
2831 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2832
2833 // xinef: override miss info after absorb / block calculations
2834 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2835 {
2836 //if (damageInfo.absorb > 0)
2837 // missInfo = SPELL_MISS_ABSORB;
2838 if (damageInfo.blocked)
2839 missInfo = SPELL_MISS_BLOCK;
2840 }
2841
2842 // Xinef: override with forced crit, only visual result
2843 if (GetSpellValue()->ForcedCritResult)
2844 {
2845 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2846 }
2847
2848 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2849
2850 // xinef: health leech handling
2852 {
2853 uint8 effIndex = EFFECT_0;
2854 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2855 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2856 break;
2857
2858 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2859
2860 // get max possible damage, don't count overkill for heal
2861 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2862
2863 if (m_caster->IsAlive())
2864 {
2865 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2866 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2867
2868 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2869 m_caster->HealBySpell(healInfo);
2870 }
2871 }
2872
2873 // Send log damage message to client
2874 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2875 // Xinef: send info to target about reflect
2876 if (reflectedSpell)
2877 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2878
2879 procEx |= createProcExtendMask(&damageInfo, missInfo);
2880 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2881
2882 caster->DealSpellDamage(&damageInfo, true, this);
2883
2884 // do procs after damage, eg healing effects
2885 // no need to check if target is alive, done in procdamageandspell
2886
2887 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2888 if (canEffectTrigger)
2889 {
2890 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE);
2891 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2892 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2893
2896 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
2897 }
2898
2899 m_damage = damageInfo.damage;
2900 }
2901 // Passive spell hits/misses or active spells only misses (only triggers)
2902 else
2903 {
2904 // Fill base damage struct (unitTarget - is real spell target)
2906 procEx |= createProcExtendMask(&damageInfo, missInfo);
2907 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2908 if (canEffectTrigger)
2909 {
2910 DamageInfo dmgInfo(damageInfo, NODAMAGE);
2911 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2912 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2913
2914 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2915 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2919 }
2920
2921 // Failed Pickpocket, reveal rogue
2923 {
2927 }
2928 }
2929
2930 if (m_caster)
2931 {
2933 {
2936
2937 // Patch 3.0.8: All player spells which cause a creature to become aggressive to you will now also immediately cause the creature to be tapped.
2938 if (effectUnit->IsInCombatWith(m_caster))
2939 {
2940 if (Creature* creature = effectUnit->ToCreature())
2941 {
2942 if (!creature->hasLootRecipient() && m_caster->IsPlayer())
2943 {
2944 creature->SetLootRecipient(m_caster);
2945 }
2946 }
2947 }
2948
2949 // Unsure if there are more spells that are not supposed to stop enemy from
2950 // regenerating HP from food, so for now it stays as an ID.
2951 const uint32 SPELL_PREMEDITATION = 14183;
2952 if (m_spellInfo->Id != SPELL_PREMEDITATION)
2953 {
2954 if (!effectUnit->IsStandState())
2955 {
2957 }
2958 }
2959 }
2960 }
2961
2962 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2964 {
2965 m_caster->SetInCombatWith(effectUnit);
2966 }
2967
2968 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2970 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2971
2972 if (spellHitTarget)
2973 {
2974 //AI functions
2975 if (spellHitTarget->IsCreature())
2976 {
2977 if (spellHitTarget->ToCreature()->IsAIEnabled)
2978 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2979 }
2980
2982 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2983
2984 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2985 DoTriggersOnSpellHit(spellHitTarget, mask);
2986
2987 // if target is fallged for pvp also flag caster if a player
2988 // xinef: do not flag spells with aura bind sight (no special attribute)
2989 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2991 {
2992 m_caster->ToPlayer()->UpdatePvP(true);
2993 }
2994
2996 }
2997}
@ NODAMAGE
Definition: Unit.h:252
@ SPELL_DIRECT_DAMAGE
Definition: Unit.h:249
@ HEAL
Definition: Unit.h:251
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
Definition: Unit.cpp:15949
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:32
@ AURA_INTERRUPT_FLAG_TALK
Definition: SpellDefines.h:54
@ PROC_EX_NO_OVERHEAL
Definition: SpellMgr.h:213
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:132
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:126
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:129
@ PROC_FLAG_TAKEN_DAMAGE
Definition: SpellMgr.h:137
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:123
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition: SpellInfo.h:183
@ SPELL_ATTR0_CU_PICKPOCKET
Definition: SpellInfo.h:186
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition: Spell.h:267
@ SPELL_EFFECT_HEALTH_LEECH
Definition: SharedDefines.h:787
@ SPELL_ATTR1_NO_THREAT
Definition: SharedDefines.h:429
@ SPELL_ATTR3_SUPRESS_CASTER_PROCS
Definition: SharedDefines.h:509
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition: SharedDefines.h:402
@ SPELL_HIT_TYPE_CRIT
Definition: SharedDefines.h:1536
SpellMissInfo
Definition: SharedDefines.h:1518
@ SPELL_MISS_DODGE
Definition: SharedDefines.h:1522
@ SPELL_MISS_IMMUNE2
Definition: SharedDefines.h:1527
@ SPELL_MISS_RESIST
Definition: SharedDefines.h:1521
@ SPELL_MISS_MISS
Definition: SharedDefines.h:1520
@ SPELL_MISS_BLOCK
Definition: SharedDefines.h:1524
@ SPELL_ATTR4_SUPRESS_WEAPON_PROCS
Definition: SharedDefines.h:553
Milliseconds GetGameTimeMS()
Definition: GameTime.cpp:43
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:27
virtual void SpellHitTarget(Unit *, SpellInfo const *)
Definition: CreatureAI.h:146
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: CreatureAI.h:143
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition: HostileRefMgr.cpp:35
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition: Creature.cpp:3805
CreatureAI * AI() const
Definition: Creature.h:143
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition: Player.cpp:9935
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition: Player.cpp:7199
void UpdatePvP(bool state, bool _override=false)
Definition: PlayerUpdates.cpp:1480
Definition: Unit.h:330
Definition: Unit.h:373
Definition: Unit.h:489
uint32 m_lastSanctuaryTime
Definition: Unit.h:1812
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition: Unit.cpp:1438
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition: Unit.cpp:6415
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition: Unit.cpp:6248
bool CanProc()
Definition: Unit.h:1673
bool IsPvP() const
Definition: Unit.h:965
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:12408
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition: Unit.cpp:13537
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition: Unit.cpp:11200
bool IsStandState() const
Definition: Unit.cpp:16675
bool IsInCombatWith(Unit const *who) const
Definition: Unit.cpp:21003
HostileRefMgr & getHostileRefMgr()
Definition: Unit.h:843
int32 GetHealthGain(int32 dVal)
Definition: Unit.cpp:14079
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition: Unit.cpp:12277
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition: Unit.cpp:6280
bool IsAIEnabled
Definition: Unit.h:1818
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition: Unit.h:1020
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:12526
void SetStandState(uint8 state)
Definition: Unit.cpp:16681
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition: Unit.cpp:5151
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition: Unit.cpp:800
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition: Unit.cpp:1295
ObjectGuid GetUnitTargetGUID() const
Definition: Spell.cpp:217
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition: Spell.cpp:8733
SpellValue const * GetSpellValue()
Definition: Spell.h:583
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition: Spell.cpp:2999
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition: Spell.cpp:3264
uint32 AttributesEx3
Definition: SpellInfo.h:327
bool IsAuraEffectEqual(SpellInfo const *otherSpellInfo) const
Definition: SpellInfo.cpp:1697
bool IsTargetingArea() const
Definition: SpellInfo.cpp:1024
bool IsPositiveEffect(uint8 effIndex) const
Definition: SpellInfo.cpp:1241

References SpellNonMeleeDamage::absorb, Creature::AI(), TargetInfo::alive, UnitAI::AttackStart(), SpellInfo::AttributesEx3, AURA_INTERRUPT_FLAG_TALK, SpellNonMeleeDamage::blocked, Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), Unit::CombatStart(), createProcExtendMask(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, Unit::DealDamageMods(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), Unit::getHostileRefMgr(), Unit::GetOwner(), Unit::GetOwnerGUID(), SpellInfo::GetSchoolMask(), GetSpellValue(), getState(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTargetGUID(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), SpellInfo::IsAuraEffectEqual(), Object::IsCreature(), Map::IsDungeon(), Unit::IsFriendlyTo(), Unit::IsInCombat(), Unit::IsInCombatWith(), Object::IsPlayer(), ObjectGuid::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsPvP(), Unit::IsStandState(), SpellInfo::IsTargetingArea(), Creature::LowerPlayerDamageReq(), m_attackType, m_caster, m_damage, m_healing, Unit::m_lastSanctuaryTime, m_needComboPoints, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellAura, m_spellInfo, m_spellSchoolMask, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, TargetInfo::missCondition, NODAMAGE, PrepareScriptHitHandlers(), PROC_EX_CRITICAL_HIT, PROC_EX_NO_OVERHEAL, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_TAKEN_DAMAGE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, Unit::ProcDamageAndSpell(), TargetInfo::processed, TargetInfo::reflectResult, Unit::RemoveAurasWithInterruptFlags(), Player::RestoreSpellMods(), TargetInfo::scaleAura, Unit::SendSpellMiss(), Unit::SendSpellNonMeleeDamageLog(), Unit::SendSpellNonMeleeReflectLog(), Unit::SetInCombatWith(), Unit::SetLastDamagedTargetGuid(), Unit::SetStandState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPRESS_CASTER_PROCS, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR4_SUPRESS_WEAPON_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HEALTH_LEECH, SPELL_HIT_TYPE_CRIT, SPELL_INTERRUPT_NONPLAYER, SPELL_MISS_BLOCK, SPELL_MISS_DODGE, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE2, SPELL_MISS_MISS, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, SPELL_MISS_RESIST, SPELL_STATE_DELAYED, Unit::SpellCriticalHealingBonus(), Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), CreatureAI::SpellHit(), CreatureAI::SpellHitTarget(), TriggeredByAuraSpellData::spellInfo, SpellNonMeleeDamage::target, TargetInfo::targetGUID, HostileRefMgr::threatAssist(), TargetInfo::timeDelay, Object::ToCreature(), Object::ToPlayer(), UNIT_STAND_STATE_STAND, unitTarget, and Player::UpdatePvP().

Referenced by _handle_immediate_phase(), handle_delayed(), and handle_immediate().

◆ DoCreateItem()

void Spell::DoCreateItem ( uint8  effIndex,
uint32  itemId 
)
1636{
1637 if (!unitTarget)
1638 return;
1639
1640 Player* player = unitTarget->ToPlayer();
1641 if (!player)
1642 {
1643 return;
1644 }
1645
1646 uint32 newitemid = itemId;
1647
1648 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1649 if (!pProto)
1650 {
1651 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1652 return;
1653 }
1654
1655 uint32 addNumber = damage;
1656
1657 // bg reward have some special in code work
1658 bool SelfCast = true;
1659 switch (m_spellInfo->Id)
1660 {
1665 case SPELL_WS_MARK_TIE:
1668 SelfCast = true;
1669 break;
1671 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1672 addNumber = 3;
1673 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1674 addNumber = 2;
1675 else
1676 addNumber = 1;
1677 SelfCast = true;
1678 break;
1679 }
1680
1681 if (addNumber < 1)
1682 addNumber = 1;
1683 if (addNumber > pProto->GetMaxStackSize())
1684 addNumber = pProto->GetMaxStackSize();
1685
1686 /* == gem perfection handling == */
1687
1688 // the chance of getting a perfect result
1689 float perfectCreateChance = 0.0f;
1690
1691 // the resulting perfect item if successful
1692 uint32 perfectItemType = itemId;
1693
1694 // get perfection capability and chance
1695 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1696 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1697 newitemid = perfectItemType; // the perfect item replaces the regular one
1698
1699 /* == gem perfection handling over == */
1700
1701 /* == profession specialization handling == */
1702
1703 // init items_count to 1, since 1 item will be created regardless of specialization
1704 int32 itemsCount = 1;
1705 float additionalCreateChance = 0.0f;
1706 int32 additionalMaxNum = 0;
1707 // get the chance and maximum number for creating extra items
1708 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1709 {
1710 // roll with this chance till we roll not to create or we create the max num
1711 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1712 ++itemsCount;
1713 }
1714
1715 // really will be created more items
1716 addNumber *= itemsCount;
1717
1718 /* == profession specialization handling over == */
1719
1720 // can the player store the new item?
1721 ItemPosCountVec dest;
1722 uint32 no_space = 0;
1723 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1724 if (msg != EQUIP_ERR_OK)
1725 {
1726 // convert to possible store amount
1728 addNumber -= no_space;
1729 else
1730 {
1731 // if not created by another reason from full inventory or unique items amount limitation
1732 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1733 return;
1734 }
1735 }
1736
1737 if (addNumber)
1738 {
1739 // create the new item and store it
1740 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1741
1742 // was it successful? return error if not
1743 if (!pItem)
1744 {
1745 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1746 return;
1747 }
1748
1749 // set the "Crafted by ..." property of the item
1750 if (pItem->GetTemplate()->HasSignature())
1751 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1752
1753 // send info to the client
1754 player->SendNewItem(pItem, addNumber, true, SelfCast);
1755
1756 sScriptMgr->OnCreateItem(player, pItem, addNumber);
1757
1758 // we succeeded in creating at least one item, so a levelup is possible
1759 if (SelfCast)
1761 }
1762}
bool canCreateExtraItems(Player *player, uint32 spellId, float &additionalChance, int32 &newMaxOrEntry)
Definition: SkillExtraItems.cpp:226
bool CanCreatePerfectItem(Player *player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
Definition: SkillExtraItems.cpp:202
@ SPELL_WS_MARK_WINNER
Definition: Battleground.h:106
@ SPELL_AV_MARK_LOSER
Definition: Battleground.h:110
@ SPELL_WS_MARK_TIE
Definition: Battleground.h:107
@ SPELL_WS_MARK_LOSER
Definition: Battleground.h:105
@ SPELL_AB_MARK_LOSER
Definition: Battleground.h:108
@ SPELL_WG_MARK_WINNER
Definition: Battleground.h:114
@ SPELL_AB_MARK_WINNER
Definition: Battleground.h:109
@ SPELL_AV_MARK_WINNER
Definition: Battleground.h:111
@ ITEM_FIELD_CREATOR
Definition: UpdateFields.h:37
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition: Item.h:70
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition: Item.h:64
bool HasSignature() const
Definition: ItemTemplate.h:698
void SetGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:723
bool UpdateCraftSkill(uint32 spellid)
Definition: PlayerUpdates.cpp:781
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition: PlayerStorage.cpp:4752
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition: PlayerStorage.cpp:2526

References canCreateExtraItems(), CanCreatePerfectItem(), Player::CanStoreNewItem(), damage, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Object::GetGUID(), ItemTemplate::GetMaxStackSize(), Item::GetTemplate(), Unit::HasAura(), ItemTemplate::HasSignature(), SpellInfo::Id, ITEM_FIELD_CREATOR, m_spellInfo, NULL_BAG, NULL_SLOT, roll_chance_f(), Player::SendEquipError(), Player::SendNewItem(), Object::SetGuidValue(), sObjectMgr, SPELL_AB_MARK_LOSER, SPELL_AB_MARK_WINNER, SPELL_AV_MARK_LOSER, SPELL_AV_MARK_WINNER, SPELL_WG_MARK_WINNER, SPELL_WS_MARK_LOSER, SPELL_WS_MARK_TIE, SPELL_WS_MARK_WINNER, sScriptMgr, Player::StoreNewItem(), Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

Referenced by SpellScript::CreateItem(), EffectCreateItem(), EffectCreateItem2(), and EffectEnchantItemPerm().

◆ DoSpellHitOnUnit()

SpellMissInfo Spell::DoSpellHitOnUnit ( Unit unit,
uint32  effectMask,
bool  scaleAura 
)
protected
Todo:
: this cause soul transfer bugged
3000{
3001 if (!unit || !effectMask)
3002 return SPELL_MISS_EVADE;
3003
3004 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
3005 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
3006 {
3007 return SPELL_MISS_IMMUNE;
3008 }
3009
3010 // disable effects to which unit is immune
3011 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
3012 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3013 {
3014 if (effectMask & (1 << effectNumber))
3015 {
3016 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
3017 effectMask &= ~(1 << effectNumber);
3018 // Xinef: Buggs out polymorph
3019 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3020 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3021 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3022 {
3023 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3024 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3025
3026 if (debuff_resist_chance > 0)
3027 if (irand(0,10000) <= (debuff_resist_chance * 100))
3028 {
3029 effectMask &= ~(1 << effectNumber);
3030 returnVal = SPELL_MISS_RESIST;
3031 }
3032 }*/
3033 }
3034 }
3035 if (!effectMask)
3036 return returnVal;
3037
3038 if (unit->IsPlayer())
3039 {
3043 }
3044
3045 if (m_caster->IsPlayer())
3046 {
3049 }
3050
3051 if (m_caster != unit)
3052 {
3053 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3054 // Xinef: Also check evade state
3055 if (m_spellInfo->Speed > 0.0f)
3056 {
3057 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
3058 return SPELL_MISS_EVADE;
3059
3061 return SPELL_MISS_EVADE;
3062 }
3063
3064 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3065 {
3067 }
3068 else if (m_caster->IsFriendlyTo(unit))
3069 {
3070 // for delayed spells ignore negative spells (after duel end) for friendly targets
3072 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
3073 return SPELL_MISS_EVADE;
3074
3075 // assisting case, healing and resurrection
3077 {
3080 m_caster->ToPlayer()->UpdatePvP(true);
3081 }
3082
3083 // xinef: triggered spells should not prolong combat
3085 {
3086 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3087 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3088 }
3089 }
3090 }
3091
3092 uint8 aura_effmask = 0;
3093 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3094 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3095 aura_effmask |= 1 << i;
3096
3097 Unit* originalCaster = GetOriginalCaster();
3098 if (!originalCaster)
3099 originalCaster = m_caster;
3100
3101 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3102 // Xinef: Do not increase diminishing level for self cast
3104 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3106 {
3109
3110 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3111
3112 // Increase Diminishing on unit, current informations for actually casts will use values above
3113 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3115 {
3116 // Do not apply diminish return if caster is NPC
3118 {
3120 }
3121 }
3122 }
3123
3125 {
3127 }
3128
3129 if (aura_effmask)
3130 {
3131 // Select rank for aura with level requirements only in specific cases
3132 // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
3133 SpellInfo const* aurSpellInfo = m_spellInfo;
3134 int32 basePoints[3];
3135 if (scaleAura)
3136 {
3138 ASSERT(aurSpellInfo);
3139 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3140 {
3141 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3142 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3143 {
3144 aurSpellInfo = m_spellInfo;
3145 break;
3146 }
3147 }
3148 }
3149
3150 if (m_originalCaster)
3151 {
3152 bool refresh = false;
3154 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3155 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3156
3157 // xinef: if aura was not refreshed, add proc ex
3158 if (!refresh)
3160
3161 if (m_spellAura)
3162 {
3163 // Prevent aura application if target is immuned
3165 {
3167 return SPELL_MISS_IMMUNE;
3168 }
3169
3170 // Set aura stack amount to desired value
3172 {
3173 if (!refresh)
3175 else
3177 }
3178
3179 // Now Reduce spell duration using data received at spell hit
3180 int32 duration = m_spellAura->GetMaxDuration();
3181 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3182
3183 // Xinef: if unit == caster - test versus original unit if available
3184 float diminishMod = 1.0f;
3185 if (unit == m_caster && m_targets.GetUnitTarget())
3187 else
3188 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3189
3190 // unit is immune to aura if it was diminished to 0 duration
3191 if (diminishMod == 0.0f)
3192 {
3195 return SPELL_MISS_IMMUNE;
3196 bool found = false;
3197 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3198 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3199 found = true;
3200 if (!found)
3201 return SPELL_MISS_IMMUNE;
3202 }
3203 else
3204 {
3205 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3206
3207 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3209 positive = aurApp->IsPositive();
3210
3211 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3212
3213 // xinef: haste affects duration of those spells twice
3216
3217 if (m_spellValue->AuraDuration != 0)
3218 {
3219 if (m_spellAura->GetMaxDuration() != -1)
3220 {
3222 }
3223
3225 }
3226 else if (duration != m_spellAura->GetMaxDuration())
3227 {
3228 m_spellAura->SetMaxDuration(duration);
3229 m_spellAura->SetDuration(duration);
3230 }
3231
3232 // xinef: apply relic cooldown, imo best place to add this
3235
3238 }
3239 }
3240 }
3241 }
3242
3243 int8 sanct_effect = -1;
3244
3245 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3246 {
3247 // handle sanctuary effects after aura apply!
3248 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3249 {
3250 sanct_effect = effectNumber;
3251 continue;
3252 }
3253
3254 if (effectMask & (1 << effectNumber))
3255 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3256 }
3257
3258 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3259 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3260
3261 return SPELL_MISS_NONE;
3262}
@ UNIT_STATE_ATTACK_PLAYER
Definition: UnitDefines.h:163
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:230
@ UNIT_MOD_CAST_SPEED
Definition: UpdateFields.h:137
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition: CreatureData.h:65
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition: CreatureData.h:66
@ SPELL_AURA_PERIODIC_HASTE
Definition: SpellAuraDefines.h:379
@ SPELL_AURA_REFLECT_SPELLS
Definition: SpellAuraDefines.h:91
@ SPELL_AURA_MOD_STEALTH
Definition: SpellAuraDefines.h:79
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition: SpellDefines.h:44
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition: SpellDefines.h:150
@ PROC_EX_NO_AURA_REFRESH
Definition: SpellMgr.h:214
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition: SpellInfo.h:182
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition: SpellMgr.cpp:276
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition: SpellMgr.cpp:59
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition: SpellMgr.cpp:246
@ DIMINISHING_TAUNT
Definition: SharedDefines.h:3276
@ SPELL_EFFECT_SANCTUARY
Definition: SharedDefines.h:857
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition: SharedDefines.h:580
DiminishingReturnsType
Definition: SharedDefines.h:3249
@ DRTYPE_PLAYER
Definition: SharedDefines.h:3251
@ DRTYPE_ALL
Definition: SharedDefines.h:3252
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition: DBCEnums.h:112
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition: DBCEnums.h:113
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition: DBCEnums.h:181
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition: DBCEnums.h:142
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition: DBCEnums.h:217
bool isWorldBoss() const
Definition: Creature.h:123
bool IsInEvadeMode() const
Definition: Creature.h:137
uint32 flags_extra
Definition: CreatureData.h:247
float GetFloatValue(uint16 index) const
Definition: Object.cpp:317
static ObjectGuid const Empty
Definition: ObjectGuid.h:120
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition: Unit.cpp:5708
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition: Unit.cpp:14961
void IncrDiminishing(DiminishingGroup group)
Definition: Unit.cpp:14987
uint32 GetCombatTimer() const
Definition: Unit.h:830
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12788
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition: Unit.cpp:17203
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:682
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition: Unit.cpp:15001
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition: Unit.cpp:14827
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition: Unit.h:1743
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition: Unit.cpp:13688
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition: Unit.h:1246
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:5675
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12703
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition: Unit.cpp:12872
bool IsImmunedToDamageOrSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12857
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:10197
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition: Unit.cpp:13833
ObjectGuid GetCharmerOrOwnerGUID() const
Definition: Unit.h:1238
Definition: SpellAuras.h:37
int32 GetMaxDuration() const
Definition: SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition: SpellAuras.cpp:995
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition: SpellAuras.cpp:2747
void _RegisterForTargets()
Definition: SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition: SpellAuras.cpp:1021
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint8 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool *refresh=nullptr, bool periodicReset=false)
Definition: SpellAuras.cpp:326
void SetDuration(int32 duration, bool withMods=false)
Definition: SpellAuras.cpp:868
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition: SpellAuras.h:183
void SetMaxDuration(int32 duration)
Definition: SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
Definition: SpellAuras.h:279
int32 AuraDuration
Definition: Spell.h:217
uint8 AuraStackAmount
Definition: Spell.h:216
Unit * GetOriginalCaster() const
Definition: Spell.h:574
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition: SpellInfo.cpp:2525

References Unit::_IsValidAttackTarget(), Aura::_RegisterForTargets(), ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, Unit::AddSpellCooldown(), Unit::ApplyDiminishingToDuration(), ASSERT, AURA_INTERRUPT_FLAG_HITBYSPELL, SpellValue::AuraDuration, SpellValue::AuraStackAmount, CREATURE_FLAG_EXTRA_ALL_DIMINISH, CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS, DIMINISHING_TAUNT, DRTYPE_ALL, DRTYPE_PLAYER, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, CreatureTemplate::flags_extra, Aura::GetApplicationOfTarget(), SpellInfo::GetAuraRankForLevel(), Unit::GetCharmerOrOwnerGUID(), Unit::GetCombatTimer(), Creature::GetCreatureTemplate(), Unit::GetDiminishing(), GetDiminishingReturnsGroupForSpell(), GetDiminishingReturnsGroupType(), GetDiminishingReturnsLimitDuration(), Object::GetEntry(), Object::GetFloatValue(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetLevel(), Aura::GetMaxDuration(), GetOriginalCaster(), Aura::GetSpellInfo(), Item::GetTemplate(), SpellCastTargets::GetUnitTarget(), HandleEffects(), SpellInfo::HasAttribute(), Unit::HasAuraType(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), Unit::HasUnitFlag(), Unit::HasUnitState(), SpellInfo::Id, Unit::IncrDiminishing(), ItemTemplate::InventoryType, INVTYPE_RELIC, Unit::IsCharmedOwnedByPlayerOrPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToDamageOrSchool(), Unit::IsImmunedToSchool(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), Object::IsPlayer(), SpellInfo::IsPositive(), IsTriggered(), Creature::isWorldBoss(), m_caster, m_CastItem, m_damage, m_diminishGroup, m_diminishLevel, m_originalCaster, m_procEx, m_spellAura, m_spellFlags, m_spellInfo, m_spellValue, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, Unit::ModSpellDuration(), Aura::ModStackAmount(), PROC_EX_NO_AURA_REFRESH, Aura::Remove(), Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Unit::SetContestedPvP(), Aura::SetDuration(), Unit::SetInCombatState(), Aura::SetMaxDuration(), Aura::SetStackAmount(), Aura::SetTriggeredByAuraSpellInfo(), SpellInfo::Speed, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_MOD_STEALTH, SPELL_AURA_PERIODIC_HASTE, SPELL_AURA_REFLECT_SPELLS, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_SANCTUARY, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_RELIC_COOLDOWN, TriggeredByAuraSpellData::spellInfo, SpellInfo::StackAmount, Player::StartTimedAchievement(), HostileRefMgr::threatAssist(), Object::ToCreature(), Object::ToPlayer(), TRIGGERED_NO_PERIODIC_RESET, Aura::TryRefreshStackOrCreate(), UNIT_FLAG_NON_ATTACKABLE, UNIT_MOD_CAST_SPEED, UNIT_STATE_ATTACK_PLAYER, unitTarget, Player::UpdateAchievementCriteria(), and Player::UpdatePvP().

Referenced by DoAllEffectOnTarget().

◆ DoTriggersOnSpellHit()

void Spell::DoTriggersOnSpellHit ( Unit unit,
uint8  effMask 
)
protected
Todo:
: move this code to scripts
Todo:
: remove/cleanup this, as this table is not documented and people are doing stupid things with it
3265{
3266 // Apply additional spell effects to target
3268 if (m_preCastSpell)
3269 {
3270 // Paladin immunity shields
3271 if (m_preCastSpell == 61988)
3272 {
3273 // Cast Forbearance
3274 m_caster->CastSpell(unit, 25771, true);
3275 // Cast Avenging Wrath Marker
3276 unit->CastSpell(unit, 61987, true);
3277 }
3278
3279 // Avenging Wrath
3280 if (m_preCastSpell == 61987)
3281 // Cast the serverside immunity shield marker
3282 m_caster->CastSpell(unit, 61988, true);
3283
3284 // Fearie Fire (Feral) - damage
3285 if (m_preCastSpell == 60089)
3286 m_caster->CastSpell(unit, m_preCastSpell, true);
3287 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3288 // Blizz seems to just apply aura without bothering to cast
3290 }
3291
3292 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3293 // this is executed after spell proc spells on target hit
3294 // spells are triggered for each hit spell target
3295 // info confirmed with retail sniffs of permafrost and shadow weaving
3296 if (!m_hitTriggerSpells.empty())
3297 {
3298 int _duration = 0;
3299 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3300 {
3301 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3302 {
3303 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3304 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3305
3306 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3307 // set duration of current aura to the triggered spell
3308 if (i->triggeredSpell->GetDuration() == -1)
3309 {
3310 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3311 {
3312 // get duration from aura-only once
3313 if (!_duration)
3314 {
3315 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3316 _duration = aur ? aur->GetDuration() : -1;
3317 }
3318 triggeredAur->SetDuration(_duration);
3319 }
3320 }
3321 }
3322 }
3323 }
3324
3325 // trigger linked auras remove/apply
3327 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3328 {
3329 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3330 if (*i < 0)
3331 {
3332 unit->RemoveAurasDueToSpell(-(*i));
3333 }
3334 else
3335 {
3336 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3337 }
3338 }
3339}
bool roll_chance_i(int chance)
Definition: Random.h:59
@ SPELL_LINK_HIT
Definition: SpellMgr.h:97
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5551
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:18818
int32 GetDuration() const
Definition: SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition: Spell.h:754

References Unit::AddAura(), CanExecuteTriggersOnHit(), Unit::CastSpell(), Unit::GetAura(), Aura::GetDuration(), Object::GetGUID(), SpellInfo::Id, LOG_DEBUG, m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_LINK_HIT, and sSpellMgr.

Referenced by DoAllEffectOnTarget().

◆ EffectActivateObject()

void Spell::EffectActivateObject ( SpellEffIndex  effIndex)
4232{
4234 return;
4235
4236 if (!gameObjTarget)
4237 return;
4238
4239 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4240 switch (action)
4241 {
4242 case GameObjectActions::AnimateCustom0:
4243 case GameObjectActions::AnimateCustom1:
4244 case GameObjectActions::AnimateCustom2:
4245 case GameObjectActions::AnimateCustom3:
4246 gameObjTarget->SendCustomAnim(uint32(action) - uint32(GameObjectActions::AnimateCustom0));
4247 break;
4248 case GameObjectActions::Disturb: // What's the difference with Open?
4249 case GameObjectActions::Open:
4250 if (Unit* unitCaster = m_caster->ToUnit())
4251 gameObjTarget->Use(unitCaster);
4252 break;
4253 case GameObjectActions::OpenAndUnlock:
4254 if (Unit* unitCaster = m_caster->ToUnit())
4255 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4256 [[fallthrough]];
4257 case GameObjectActions::Unlock:
4258 case GameObjectActions::Lock:
4259 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED, action == GameObjectActions::Lock);
4260 break;
4261 case GameObjectActions::Close:
4262 case GameObjectActions::Rebuild:
4264 break;
4265 case GameObjectActions::Despawn:
4267 break;
4268 case GameObjectActions::MakeInert:
4269 case GameObjectActions::MakeActive:
4270 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE, action == GameObjectActions::MakeInert);
4271 break;
4272 case GameObjectActions::CloseAndLock:
4275 break;
4276 case GameObjectActions::Destroy:
4277 if (Unit* unitCaster = m_caster->ToUnit())
4278 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4279 break;
4280 case GameObjectActions::UseArtKit0:
4281 case GameObjectActions::UseArtKit1:
4282 case GameObjectActions::UseArtKit2:
4283 case GameObjectActions::UseArtKit3:
4284 {
4285 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4286
4287 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4288
4289 uint32 artKitValue = 0;
4290 if (templateAddon)
4291 artKitValue = templateAddon->artKits[artKitIndex];
4292
4293 if (artKitValue == 0)
4294 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4295 else
4296 gameObjTarget->SetGoArtKit(artKitValue);
4297
4298 break;
4299 }
4300 case GameObjectActions::None:
4301 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4302 break;
4303 default:
4304 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4305 break;
4306 }
4307}
#define LOG_FATAL(filterType__,...)
Definition: Log.h:152
@ GAMEOBJECT_FLAGS
Definition: UpdateFields.h:399
GameObjectActions
Definition: GameObject.h:77
@ GO_FLAG_NOT_SELECTABLE
Definition: SharedDefines.h:1607
@ GO_FLAG_LOCKED
Definition: SharedDefines.h:1604
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition: GameObject.cpp:1429
void SetGoArtKit(uint8 artkit)
Definition: GameObject.cpp:1443
void SendCustomAnim(uint32 anim)
Definition: GameObject.cpp:2150
void ResetDoorOrButton()
Definition: GameObject.cpp:1419
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition: GameObject.cpp:933
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition: GameObject.cpp:912
void Use(Unit *user)
Definition: GameObject.cpp:1479
Definition: GameObjectData.h:664
std::array< uint32, 4 > artKits
Definition: GameObjectData.h:670
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:845
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition: Object.cpp:899

References Object::ApplyModFlag(), GameObjectTemplateAddon::artKits, GameObject::DespawnOrUnsummon(), effectHandleMode, SpellInfo::Effects, GAMEOBJECT_FLAGS, gameObjTarget, Object::GetEntry(), GameObject::GetTemplateAddon(), GO_FLAG_LOCKED, GO_FLAG_NOT_SELECTABLE, SpellInfo::Id, LOG_ERROR, LOG_FATAL, m_caster, m_spellInfo, GameObject::ResetDoorOrButton(), GameObject::SendCustomAnim(), Object::SetFlag(), GameObject::SetGoArtKit(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToUnit(), GameObject::Use(), and GameObject::UseDoorOrButton().

◆ EffectActivateRune()

void Spell::EffectActivateRune ( SpellEffIndex  effIndex)
5746{
5748 return;
5749
5750 if (!m_caster->IsPlayer())
5751 return;
5752
5753 Player* player = m_caster->ToPlayer();
5754
5756 return;
5757
5758 // needed later
5760
5761 uint32 count = damage;
5762 if (count == 0) count = 1;
5763 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5764 {
5765 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5766 {
5767 if (m_spellInfo->Id == 45529)
5768 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5769 continue;
5770 player->SetRuneCooldown(j, 0);
5771 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5772 --count;
5773 }
5774 }
5775
5776 // Blood Tap
5777 if (m_spellInfo->Id == 45529 && count > 0)
5778 {
5779 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5780 {
5781 // Check if both runes are on cd as that is the only time when this needs to come into effect
5782 if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
5783 {
5784 // Should always update the rune with the lowest cd
5785 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5786 l++;
5787 player->SetRuneCooldown(l, 0);
5788 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5789 --count;
5790 }
5791 else
5792 break;
5793 }
5794 }
5795
5796 // Empower rune weapon
5797 if (m_spellInfo->Id == 47568)
5798 {
5799 // Need to do this just once
5800 if (effIndex != 0)
5801 return;
5802
5803 for (uint32 i = 0; i < MAX_RUNES; ++i)
5804 {
5805 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5806 {
5807 player->SetRuneCooldown(i, 0);
5808 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5809 }
5810 }
5811 }
5812
5813 // is needed to push through to the client that the rune is active
5814 //player->ResyncRunes(MAX_RUNES);
5815 m_caster->CastSpell(m_caster, 47804, true);
5816}
@ RUNE_FROST
Definition: Player.h:411
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition: Player.h:2498
uint8 GetRunesState() const
Definition: Player.h:2487
void SetGracePeriod(uint8 index, uint32 period)
Definition: Player.h:2499
RuneType GetBaseRune(uint8 index) const
Definition: Player.h:2488

References Unit::CastSpell(), CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, damage, effectHandleMode, SpellInfo::Effects, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Player::GetRunesState(), SpellInfo::Id, Player::IsClass(), Unit::IsInCombat(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, RUNE_DEATH, RUNE_FROST, Player::SetGracePeriod(), Player::SetRuneCooldown(), SPELL_EFFECT_HANDLE_LAUNCH, and Object::ToPlayer().

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6121{
6123 return;
6124
6125 if (!unitTarget)
6126 return;
6127
6128 if (Player* player = unitTarget->ToPlayer())
6129 {
6130 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6131 }
6132}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4069{
4071 {
4072 return;
4073 }
4074
4075 if (!unitTarget || damage <= 0)
4076 {
4077 return;
4078 }
4079
4081}
void AddComboPointGain(Unit *target, int8 amount)
Definition: Spell.h:530

References AddComboPointGain(), damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddExtraAttacks()

void Spell::EffectAddExtraAttacks ( SpellEffIndex  effIndex)
4651{
4653 {
4654 return;
4655 }
4656
4657 if (!unitTarget || !unitTarget->IsAlive())
4658 {
4659 return;
4660 }
4661
4663
4665}
void AddExtraAttacks(uint32 count)
Definition: Unit.cpp:2748
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition: Spell.cpp:5115

References Unit::AddExtraAttacks(), damage, effectHandleMode, ExecuteLogEffectExtraAttacks(), Unit::IsAlive(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2696{
2698 return;
2699
2700 if (!m_caster->IsPlayer())
2701 return;
2702
2703 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2704 int32 duration = m_spellInfo->GetDuration();
2705 // Caster not in world, might be spell triggered from aura removal
2706 if (!m_caster->IsInWorld())
2707 return;
2708
2709 // Remove old farsight if exist
2710 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2711
2712 DynamicObject* dynObj = new DynamicObject(true);
2713 if (!dynObj->CreateDynamicObject(m_caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
2714 {
2715 delete dynObj;
2716 return;
2717 }
2718
2719 dynObj->SetDuration(duration);
2720 dynObj->SetCasterViewpoint(updateViewerVisibility);
2721}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition: DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition: DynamicObject.cpp:203
void SetCasterViewpoint(bool updateViewerVisibility)
Definition: DynamicObject.cpp:231
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, uint32 spellId, Position const &pos, float radius, DynamicObjectType type)
Definition: DynamicObject.cpp:97
ObjectGuid::LowType GenerateLowGuid()
Definition: Map.h:638

References DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_FARSIGHT_FOCUS, effectHandleMode, SpellInfo::Effects, Map::GenerateLowGuid(), SpellInfo::GetDuration(), WorldObject::GetMap(), SpellInfo::Id, Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::RemoveDynObject(), DynamicObject::SetCasterViewpoint(), DynamicObject::SetDuration(), and SPELL_EFFECT_HANDLE_HIT.

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2766{
2768 return;
2769
2770 if (!unitTarget->IsPlayer())
2771 return;
2772
2773 // not scale value for item based reward (/10 value expected)
2774 if (m_CastItem)
2775 {
2776 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2777 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2779 return;
2780 }
2781
2782 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2783 if (damage <= 50)
2784 {
2786 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2787 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2788 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2789 }
2790 else
2791 {
2792 //maybe we have correct honor_gain in damage already
2793 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2794 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2796 }
2797}
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition: Formulas.h:38
std::string ToString() const
Definition: ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition: Player.cpp:6064

References damage, effectHandleMode, Object::GetEntry(), Object::GetGUID(), Unit::GetLevel(), Acore::Honor::hk_honor_at_level(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_CastItem, m_spellInfo, Player::RewardHonor(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectApplyAreaAura()

void Spell::EffectApplyAreaAura ( SpellEffIndex  effIndex)
1308{
1310 return;
1311
1312 if (!m_spellAura || !unitTarget)
1313 return;
1316}
WorldObject * GetOwner() const
Definition: SpellAuras.h:107
void _ApplyEffectForTargets(uint8 effIndex)
Definition: SpellAuras.cpp:735

References Aura::_ApplyEffectForTargets(), ASSERT, effectHandleMode, Aura::GetOwner(), m_spellAura, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectApplyAura()

void Spell::EffectApplyAura ( SpellEffIndex  effIndex)

◆ EffectApplyGlyph()

void Spell::EffectApplyGlyph ( SpellEffIndex  effIndex)
4310{
4312 return;
4313
4315 return;
4316
4317 Player* player = m_caster->ToPlayer();
4318
4319 // glyph sockets level requirement
4320 uint8 minLevel = 0;
4321 switch (m_glyphIndex)
4322 {
4323 case 0:
4324 case 1:
4325 minLevel = 15;
4326 break;
4327 case 2:
4328 minLevel = 50;
4329 break;
4330 case 3:
4331 minLevel = 30;
4332 break;
4333 case 4:
4334 minLevel = 70;
4335 break;
4336 case 5:
4337 minLevel = 80;
4338 break;
4339 }
4340 if (minLevel && m_caster->GetLevel() < minLevel)
4341 {
4343 return;
4344 }
4345
4346 // apply new one
4347 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4348 {
4349 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4350 {
4351 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4352 {
4353 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4354 {
4356 return; // glyph slot mismatch
4357 }
4358 }
4359
4360 // remove old glyph aura
4361 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4362 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4363 {
4364 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4365
4366 // Removed any triggered auras
4367 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4368 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4369 {
4370 Aura* aura = iter->second;
4371 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4372 {
4373 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4374 {
4375 player->RemoveOwnedAura(iter);
4376 continue;
4377 }
4378 }
4379 ++iter;
4380 }
4381
4382 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4383 }
4384
4385 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4387 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4388 player->SendTalentsInfoData(false);
4389 }
4390 }
4391}
DBCStorage< GlyphSlotEntry > sGlyphSlotStore(GlyphSlotfmt)
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition: SpellDefines.h:148
#define MAX_GLYPH_SLOT_INDEX
Definition: SharedDefines.h:676
@ SPELL_FAILED_GLYPH_SOCKET_LOCKED
Definition: SharedDefines.h:1126
@ SPELL_FAILED_INVALID_GLYPH
Definition: SharedDefines.h:1124
void SendTalentsInfoData(bool pet)
Definition: Player.cpp:14424
void SendLearnPacket(uint32 spellId, bool learn)
Definition: Player.cpp:3019
uint32 GetGlyph(uint8 slot) const
Definition: Player.h:1752
uint32 GetGlyphSlot(uint8 slot) const
Definition: Player.h:1743
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition: Player.h:1744
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4686
std::multimap< uint32, Aura * > AuraMap
Definition: Unit.h:635
AuraMap & GetOwnedAuras()
Definition: Unit.h:1321
bool PlayerLoading() const
Definition: WorldSession.h:337
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition: SpellAuras.cpp:2761
Definition: DBCStructure.h:1028

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, Player::GetGlyph(), Player::GetGlyphSlot(), Unit::GetLevel(), Unit::GetOwnedAuras(), Player::GetSession(), Aura::GetTriggeredByAuraSpellInfo(), Object::IsPlayer(), m_caster, m_glyphIndex, m_spellInfo, MAX_GLYPH_SLOT_INDEX, WorldSession::PlayerLoading(), Unit::RemoveAurasDueToSpell(), Unit::RemoveOwnedAura(), SendCastResult(), Player::SendLearnPacket(), Player::SendTalentsInfoData(), Player::SetGlyph(), sGlyphPropertiesStore, sGlyphSlotStore, SPELL_EFFECT_HANDLE_HIT, SPELL_FAILED_GLYPH_SOCKET_LOCKED, SPELL_FAILED_INVALID_GLYPH, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_IGNORE_CASTER_AURASTATE, and TRIGGERED_IGNORE_SHAPESHIFT.

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6254{
6256 return;
6257
6258 if (!unitTarget)
6259 return;
6260
6261 Player* player = unitTarget->ToPlayer();
6262 if (!player)
6263 {
6264 return;
6265 }
6266
6267 WorldLocation homeLoc;
6268 uint32 areaId = player->GetAreaId();
6269
6270 if (m_spellInfo->Effects[effIndex].MiscValue)
6271 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6272
6273 if (m_targets.HasDst())
6274 homeLoc.WorldRelocate(*destTarget);
6275 else
6276 {
6277 homeLoc = player->GetWorldLocation();
6278 }
6279
6280 player->SetHomebind(homeLoc, areaId);
6281
6282 // binding
6283 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6284 data << float(homeLoc.GetPositionX());
6285 data << float(homeLoc.GetPositionY());
6286 data << float(homeLoc.GetPositionZ());
6287 data << uint32(homeLoc.GetMapId());
6288 data << uint32(areaId);
6289 player->SendDirectMessage(&data);
6290
6291 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6292 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6293 // zone update
6294 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6295 data << m_caster->GetGUID();
6296 data << uint32(areaId);
6297 player->SendDirectMessage(&data);
6298}
@ SMSG_BINDPOINTUPDATE
Definition: Opcodes.h:371
@ SMSG_PLAYERBOUND
Definition: Opcodes.h:374
Definition: Position.h:251
void WorldRelocate(const WorldLocation &loc)
Definition: Position.h:259
void GetWorldLocation(uint32 &mapId, float &x, float &y) const
Definition: Position.h:281
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:5692
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition: PlayerStorage.cpp:4898

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetAreaId(), Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldLocation::GetWorldLocation(), SpellCastTargets::HasDst(), WorldPacket::Initialize(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, Player::SendDirectMessage(), Player::SetHomebind(), SMSG_BINDPOINTUPDATE, SMSG_PLAYERBOUND, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), unitTarget, and WorldLocation::WorldRelocate().

◆ EffectBlock()

void Spell::EffectBlock ( SpellEffIndex  effIndex)
4677{
4679 return;
4680
4681 if (m_caster->IsPlayer())
4682 m_caster->ToPlayer()->SetCanBlock(true);
4683}
void SetCanBlock(bool value)
Definition: Player.cpp:13136

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanBlock(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectCastButtons()

void Spell::EffectCastButtons ( SpellEffIndex  effIndex)

Action button data is unverified when it's set so it can be "hacked" to contain invalid spells, so filter here.

6181{
6183 return;
6184
6185 if (!m_caster->IsPlayer())
6186 return;
6187
6188 Player* p_caster = m_caster->ToPlayer();
6189 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6190 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6191
6192 for (; n_buttons; --n_buttons, ++button_id)
6193 {
6194 ActionButton const* ab = p_caster->GetActionButton(button_id);
6195 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6196 continue;
6197
6200 uint32 spell_id = ab->GetAction();
6201 if (!spell_id)
6202 continue;
6203
6204 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6205 if (!spellInfo)
6206 continue;
6207
6208 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6209 continue;
6210
6212 continue;
6213
6214 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6215 if (m_caster->GetPower(POWER_MANA) < cost)
6216 continue;
6217
6219 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6220 }
6221}
@ ACTION_BUTTON_SPELL
Definition: Player.h:229
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition: SharedDefines.h:646
Definition: Player.h:253
uint32 GetAction() const
Definition: Player.h:261
ActionButtonType GetType() const
Definition: Player.h:260
ActionButton const * GetActionButton(uint8 button)
Definition: Player.cpp:5638
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3859

References ACTION_BUTTON_SPELL, SpellInfo::CalcPowerCost(), Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, ActionButton::GetAction(), Player::GetActionButton(), Unit::GetPower(), SpellInfo::GetSchoolMask(), ActionButton::GetType(), SpellInfo::HasAttribute(), Player::HasSpell(), Player::HasSpellCooldown(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_MANA, SPELL_ATTR7_CAN_BE_MULTI_CAST, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and TRIGGERED_IGNORE_GCD.

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4896{
4898 {
4899 if (!unitTarget)
4900 return;
4901
4902 ObjectGuid targetGUID = ObjectGuid::Empty;
4903 Player* player = m_caster->ToPlayer();
4904 if (player)
4905 {
4906 // charge changes fall time
4908
4910 {
4911 targetGUID = unitTarget->GetGUID();
4912 }
4913 }
4914
4915 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4916 // Spell is not using explicit target - no generated path
4917 if (!m_preGeneratedPath)
4918 {
4920 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4921 }
4922 else
4923 {
4924 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4925 }
4926
4927 if (player)
4928 {
4929 sScriptMgr->AnticheatSetUnderACKmount(player);
4930 }
4931 }
4932}
#define SPEED_CHARGE
Definition: MotionMaster.h:107
@ EVENT_CHARGE
Definition: SharedDefines.h:3311
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition: Object.cpp:2823
Definition: Position.h:28
float m_positionZ
Definition: Position.h:58
float GetRelativeAngle(const Position *pos) const
Definition: Position.h:197
float m_positionX
Definition: Position.h:56
float m_positionY
Definition: Position.h:57
void SetFallInformation(uint32 time, float z)
Definition: Player.h:2318
MotionMaster * GetMotionMaster()
Definition: Unit.h:1615
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, const Movement::PointsArray *path=nullptr, bool generatePath=false, float orientation=0.0f, ObjectGuid targetGUID=ObjectGuid::Empty)
The unit will charge the target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition: MotionMaster.cpp:670

References effectHandleMode, ObjectGuid::Empty, EVENT_CHARGE, Unit::GetCombatReach(), WorldObject::GetFirstCollisionPosition(), GameTime::GetGameTime(), Object::GetGUID(), Unit::GetMotionMaster(), Position::GetPositionZ(), Position::GetRelativeAngle(), Unit::GetTarget(), SpellInfo::HasAttribute(), SpellInfo::IsPositive(), m_caster, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_preGeneratedPath, m_spellInfo, MotionMaster::MoveCharge(), Player::SetFallInformation(), SpellInfo::Speed, SPEED_CHARGE, SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectChargeDest()

◆ EffectCreateItem()

void Spell::EffectCreateItem ( SpellEffIndex  effIndex)
1765{
1767 return;
1768
1769 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1770 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1771}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5143
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition: SpellEffects.cpp:1635

References DoCreateItem(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectCreateItem(), m_spellInfo, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectCreateItem2()

void Spell::EffectCreateItem2 ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1774{
1776 return;
1777
1778 if (!unitTarget)
1779 return;
1780
1781 Player* player = unitTarget->ToPlayer();
1782 if (!player)
1783 {
1784 return;
1785 }
1786
1787 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1788
1789 if (itemId)
1790 DoCreateItem(effIndex, itemId);
1791
1792 // special case: fake item replaced by generate using spell_loot_template
1794 {
1795 if (itemId)
1796 {
1797 if (!player->HasItemCount(itemId))
1798 return;
1799
1800 // remove reagent
1801 uint32 count = 1;
1802 player->DestroyItemCount(itemId, count, true);
1803
1804 // create some random items
1806 }
1807 else
1808 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1809 }
1811}
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false)
Definition: Player.cpp:13491
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition: PlayerStorage.cpp:3123
bool IsLootCrafting() const
Definition: SpellInfo.cpp:924

References Player::AutoStoreLoot(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Player::HasItemCount(), SpellInfo::Id, SpellInfo::IsLootCrafting(), LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateRandomItem()

void Spell::EffectCreateRandomItem ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1814{
1816 return;
1817
1818 if (!unitTarget)
1819 return;
1820
1821 Player* player = unitTarget->ToPlayer();
1822 if (!player)
1823 {
1824 return;
1825 }
1826
1827 // create some random items
1830}

References Player::AutoStoreLoot(), effectHandleMode, SpellInfo::Id, LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateTamedPet()

void Spell::EffectCreateTamedPet ( SpellEffIndex  effIndex)
5819{
5821 return;
5822
5824 return;
5825
5826 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5827 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5828 if (!pet)
5829 return;
5830
5831 // add to world
5832 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5833
5834 // unitTarget has pet now
5835 unitTarget->SetMinion(pet, true);
5836
5837 pet->InitTalentForLevel();
5838
5839 if (unitTarget->IsPlayer())
5840 {
5843 }
5844}
@ CLASS_HUNTER
Definition: SharedDefines.h:143
void InitTalentForLevel()
Definition: Pet.cpp:2225
void SavePetToDB(PetSaveMode mode)
Definition: Pet.cpp:507
void PetSpellInitialize()
Definition: Player.cpp:9468
void SetMinion(Minion *minion, bool apply)
Definition: Unit.cpp:10641
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition: Unit.cpp:17306
bool AddToMap(T *, bool checkTransport=false)
Definition: Map.cpp:555

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), effectHandleMode, SpellInfo::Effects, WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsPlayer(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), and unitTarget.

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5230{
5232 return;
5233
5234 int32 mana = 0;
5235 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
5236 {
5237 if (!m_caster->m_SummonSlot[slot])
5238 continue;
5239
5241 if (totem && totem->IsTotem())
5242 {
5243 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5244 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5245 if (spellInfo)
5246 {
5247 mana += spellInfo->ManaCost;
5249 }
5250 totem->ToTotem()->UnSummon();
5251 }
5252 }
5253 ApplyPct(mana, damage);
5254 if (mana)
5255 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5256}
T ApplyPct(T &base, U pct)
Definition: Util.h:73
#define SUMMON_SLOT_TOTEM
Definition: Unit.h:597
#define MAX_TOTEM_SLOT
Definition: Unit.h:598
@ UNIT_CREATED_BY_SPELL
Definition: UpdateFields.h:138
void UnSummon(uint32 msTime=0) override
Definition: Totem.cpp:122
Totem * ToTotem()
Definition: Unit.h:1729
SpellCastResult CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1224
uint32 GetCreateMana() const
Definition: Unit.h:1448
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition: Unit.h:1797
Creature * GetCreature(ObjectGuid const guid)
Definition: Map.cpp:3314
uint32 ManaCostPercentage
Definition: SpellInfo.h:367
uint32 ManaCost
Definition: SpellInfo.h:363

References ApplyPct(), CalculatePct(), Unit::CastCustomSpell(), damage, effectHandleMode, Unit::GetCreateMana(), Map::GetCreature(), WorldObject::GetMap(), Object::GetUInt32Value(), Unit::IsTotem(), m_caster, Unit::m_SummonSlot, SpellInfo::ManaCost, SpellInfo::ManaCostPercentage, MAX_TOTEM_SLOT, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, SUMMON_SLOT_TOTEM, Unit::ToTotem(), UNIT_CREATED_BY_SPELL, and Totem::UnSummon().

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5847{
5849 return;
5850
5851 if (!unitTarget)
5852 return;
5853
5854 Player* player = unitTarget->ToPlayer();
5855 if (!player)
5856 {
5857 return;
5858 }
5859
5860 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5861 if (sTaxiNodesStore.LookupEntry(nodeid))
5862 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5863}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition: TaxiHandler.cpp:151

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), m_spellInfo, WorldSession::SendDiscoverNewTaxiNode(), SPELL_EFFECT_HANDLE_HIT_TARGET, sTaxiNodesStore, Object::ToPlayer(), and unitTarget.

◆ EffectDisEnchant()

void Spell::EffectDisEnchant ( SpellEffIndex  effIndex)
4447{
4449 return;
4450
4452 return;
4453
4454 if (Player* caster = m_caster->ToPlayer())
4455 {
4456 caster->UpdateCraftSkill(m_spellInfo->Id);
4457 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4458 }
4459
4460 // item will be removed at disenchanting end
4461}
@ LOOT_DISENCHANTING
Definition: LootMgr.h:84

References ItemTemplate::DisenchantID, effectHandleMode, Object::GetGUID(), Item::GetTemplate(), SpellInfo::Id, itemTarget, LOOT_DISENCHANTING, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectDismissPet()

void Spell::EffectDismissPet ( SpellEffIndex  effIndex)
4533{
4535 return;
4536
4537 if (!unitTarget || !unitTarget->IsPet())
4538 return;
4539
4540 Pet* pet = unitTarget->ToPet();
4541
4542 ExecuteLogEffectUnsummonObject(effIndex, pet);
4544}
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:45
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition: Pet.cpp:884
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5161

References effectHandleMode, ExecuteLogEffectUnsummonObject(), Unit::IsPet(), PET_SAVE_NOT_IN_SLOT, Pet::Remove(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), and unitTarget.

◆ EffectDispel()

void Spell::EffectDispel ( SpellEffIndex  effIndex)
2545{
2547 return;
2548
2549 if (!unitTarget)
2550 return;
2551
2552 // Create dispel mask by dispel type
2553 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
2554 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2555
2556 DispelChargesList dispel_list;
2557 unitTarget->GetDispellableAuraList(m_caster, dispelMask, dispel_list, m_spellInfo);
2558 if (dispel_list.empty())
2559 return;
2560
2561 // Ok if exist some buffs for dispel try dispel it
2562 uint32 failCount = 0;
2563 DispelChargesList success_list;
2564 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2565 // dispel N = damage buffs (or while exist buffs for dispel)
2566 for (int32 count = 0; count < damage && !dispel_list.empty();)
2567 {
2568 // Random select buff for dispel
2569 DispelChargesList::iterator itr = dispel_list.begin();
2570 std::advance(itr, urand(0, dispel_list.size() - 1));
2571
2572 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
2573 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2574 if (!chance)
2575 {
2576 dispel_list.erase(itr);
2577 continue;
2578 }
2579 else
2580 {
2581 if (roll_chance_i(chance))
2582 {
2583 bool alreadyListed = false;
2584 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
2585 {
2586 if (successItr->first->GetId() == itr->first->GetId())
2587 {
2588 ++successItr->second;
2589 alreadyListed = true;
2590 }
2591 }
2592 if (!alreadyListed)
2593 success_list.push_back(std::make_pair(itr->first, 1));
2594 --itr->second;
2595 if (itr->second <= 0)
2596 dispel_list.erase(itr);
2597 }
2598 else
2599 {
2600 if (!failCount)
2601 {
2602 // Failed to dispell
2603 dataFail << m_caster->GetGUID(); // Caster GUID
2604 dataFail << unitTarget->GetGUID(); // Victim GUID
2605 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2606 }
2607 ++failCount;
2608 dataFail << uint32(itr->first->GetId()); // Spell Id
2609 }
2610 ++count;
2611 }
2612 }
2613
2614 if (failCount)
2615 m_caster->SendMessageToSet(&dataFail, true);
2616
2617 // put in combat
2620
2621 if (success_list.empty())
2622 return;
2623
2624 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2625 // Send packet header
2626 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2627 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
2628 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2629 dataSuccess << uint8(0); // not used
2630 dataSuccess << uint32(success_list.size()); // count
2631 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2632 {
2633 // Send dispelled spell info
2634 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2635 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2636 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
2637 }
2638 m_caster->SendMessageToSet(&dataSuccess, true);
2639
2640 // On success dispel
2641 // Devour Magic
2643 {
2644 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2645 m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true);
2646 // Glyph of Felhunter
2647 if (Unit* owner = m_caster->GetOwner())
2648 if (owner->GetAura(56249))
2649 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2650 }
2651}
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
@ SPELLCATEGORY_DEVOUR_MAGIC
Definition: SpellMgr.h:40
@ SPELLFAMILY_WARLOCK
Definition: SharedDefines.h:3533
@ SMSG_DISPEL_FAILED
Definition: Opcodes.h:640
@ SMSG_SPELLDISPELLOG
Definition: Opcodes.h:665
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition: Unit.cpp:5575
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit *dispeller, uint8 chargesRemoved=1)
Definition: Unit.cpp:4923
uint32 GetCategory() const
Definition: SpellInfo.cpp:870

References Unit::CastCustomSpell(), damage, EFFECT_1, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetOwner(), Object::GetPackGUID(), SpellInfo::Id, Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellByDispel(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLDISPELLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLCATEGORY_DEVOUR_MAGIC, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyName, HostileRefMgr::threatAssist(), unitTarget, and urand().

◆ EffectDispelMechanic()

void Spell::EffectDispelMechanic ( SpellEffIndex  effIndex)
5135{
5137 return;
5138
5139 if (!unitTarget)
5140 return;
5141
5142 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5143
5144 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5145
5146 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5147 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5148 {
5149 Aura* aura = itr->second;
5151 continue;
5153 {
5154 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5155 {
5156 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5157
5158 // spell only removes 1 bleed effect do not continue
5159 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5160 {
5161 break;
5162 }
5163 }
5164 }
5165 }
5166
5167 for (; dispel_list.size(); dispel_list.pop())
5168 {
5169 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5170 }
5171
5172 // put in combat
5175}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition: SpellAuraDefines.h:394
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4757
ObjectGuid GetCasterGUID() const
Definition: SpellAuras.h:105
uint32 GetId() const
Definition: SpellAuras.cpp:466
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition: SpellAuras.cpp:1182

References AURA_REMOVE_BY_ENEMY_SPELL, Aura::CalcDispelChance(), effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Aura::GetApplicationOfTarget(), Aura::GetCasterGUID(), Object::GetGUID(), Unit::getHostileRefMgr(), Aura::GetId(), Unit::GetOwnedAuras(), Aura::GetSpellInfo(), Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAura(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, HostileRefMgr::threatAssist(), and unitTarget.

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving.

2668{
2670 return;
2671
2672 // Check for possible target
2673 if (!unitTarget || unitTarget->IsEngaged())
2674 return;
2675
2676 // target must be OK to do this
2678 return;
2679
2682}
@ UNIT_STATE_CONFUSED
Definition: UnitDefines.h:160
@ UNIT_STATE_FLEEING
Definition: UnitDefines.h:156
@ UNIT_STATE_STUNNED
Definition: UnitDefines.h:152
float GetAngle(const Position *pos) const
Definition: Position.cpp:77
void SetFacingTo(float ori)
Definition: Unit.cpp:20492
bool IsEngaged() const
Definition: Unit.h:817
void MoveDistract(uint32 time)
Enable the target's distract movement. Doesn't work with UNIT_FLAG_DISABLE_MOVE and if the unit has M...
Definition: MotionMaster.cpp:798

References damage, destTarget, effectHandleMode, Position::GetAngle(), Unit::GetMotionMaster(), Unit::HasUnitState(), IN_MILLISECONDS, Unit::IsEngaged(), MotionMaster::MoveDistract(), Unit::SetFacingTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_CONFUSED, UNIT_STATE_FLEEING, UNIT_STATE_STUNNED, and unitTarget.

◆ EffectDualWield()

void Spell::EffectDualWield ( SpellEffIndex  effIndex)
2654{
2656 return;
2657
2659}
virtual void SetCanDualWield(bool value)
Definition: Unit.h:769

References effectHandleMode, Unit::SetCanDualWield(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4084{
4086 return;
4087
4088 if (!unitTarget || !m_caster->IsPlayer() || !unitTarget->IsPlayer())
4089 return;
4090
4091 Player* caster = m_caster->ToPlayer();
4092 Player* target = unitTarget->ToPlayer();
4093
4094 // caster or target already have requested duel
4095 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4096 return;
4097
4098 // Players can only fight a duel in zones with this flag
4099 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4100 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4101 {
4102 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4103 return;
4104 }
4105
4106 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4107 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4108 {
4109 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4110 return;
4111 }
4112
4113 //CREATE DUEL FLAG OBJECT
4114 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4115 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4116
4117 Map* map = m_caster->GetMap();
4118 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4119 map, m_caster->GetPhaseMask(),
4123 m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4124 {
4125 delete pGameObj;
4126 return;
4127 }
4128
4131 int32 duration = m_spellInfo->GetDuration();
4132 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4133 pGameObj->SetSpellId(m_spellInfo->Id);
4134
4135 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4136
4137 m_caster->AddGameObject(pGameObj);
4138 map->AddToMap(pGameObj, true);
4139 //END
4140
4141 // Send request
4142 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4143 data << pGameObj->GetGUID();
4144 data << caster->GetGUID();
4145 caster->GetSession()->SendPacket(&data);
4146 target->GetSession()->SendPacket(&data);
4147
4148 // create duel-info
4149 bool isMounted = (GetSpellInfo()->Id == 62875);
4150 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4151 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4152
4153 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4154 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4155
4156 sScriptMgr->OnPlayerDuelRequest(target, caster);
4157}
@ PLAYER_DUEL_ARBITER
Definition: UpdateFields.h:177
@ GAMEOBJECT_LEVEL
Definition: UpdateFields.h:403
@ GAMEOBJECT_FACTION
Definition: UpdateFields.h:402
@ SPELL_FAILED_NO_DUELING
Definition: SharedDefines.h:1028
@ AREA_FLAG_ALLOW_DUELS
Definition: DBCEnums.h:240
@ SMSG_DUEL_REQUESTED
Definition: Opcodes.h:389
virtual bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const &rotation, uint32 animprogress, GOState go_state, uint32 artKit=0)
Definition: GameObject.cpp:254
void SetRespawnTime(int32 respawn)
Definition: GameObject.cpp:1303
void SetSpellId(uint32 id)
Definition: GameObject.h:177
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:650
uint32 GetPhaseMask() const
Definition: Object.h:446
float GetOrientation() const
Definition: Position.h:120
PlayerSocial * GetSocial()
Definition: Player.h:1141
bool HasIgnore(ObjectGuid ignore_guid) const
Definition: SocialMgr.cpp:193
Definition: Transport.h:112
uint32 GetFaction() const
Definition: Unit.h:755
void AddGameObject(GameObject *gameObj)
Definition: Unit.cpp:6149
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition: WorldSession.cpp:214
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5155
uint32 flags
Definition: DBCStructure.h:523

References Unit::AddGameObject(), Map::AddToMap(), AREA_FLAG_ALLOW_DUELS, GameObject::Create(), Player::duel, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), AreaTableEntry::flags, GAMEOBJECT_FACTION, GAMEOBJECT_LEVEL, Map::GenerateLowGuid(), WorldObject::GetAreaId(), SpellInfo::GetDuration(), Unit::GetFaction(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSession(), Player::GetSocial(), GetSpellInfo(), GO_STATE_READY, PlayerSocial::HasIgnore(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), m_caster, m_spellInfo, PLAYER_DUEL_ARBITER, sAreaTableStore, SendCastResult(), WorldSession::SendPacket(), Object::SetGuidValue(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), Object::SetUInt32Value(), SMSG_DUEL_REQUESTED, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_NO_DUELING, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectDummy()

void Spell::EffectDummy ( SpellEffIndex  effIndex)
667{
669 return;
670
672 return;
673
674 // selection by spell family
676 {
678 {
679 switch (m_spellInfo->Id)
680 {
681 // Trial of the Champion, Trample
682 case 67866:
683 {
685 unitTarget->CastSpell(unitTarget, 67867, false);
686 return;
687 }
688 // Trial of the Champion, Hammer of the Righteous
689 case 66867:
690 {
691 if (!unitTarget)
692 return;
693 if (unitTarget->HasAura(66940))
694 m_caster->CastSpell(unitTarget, 66903, true);
695 else
696 m_caster->CastSpell(unitTarget, 66904, true);
697 return;
698 }
699 case 17731:
700 case 69294:
701 {
703 return;
704
708 trigger->CastSpell(trigger, 17731, false);
709
710 return;
711 }
712 // HoL, Arc Weld
713 case 59086:
714 {
716 m_caster->CastSpell(m_caster, 59097, true);
717
718 return;
719 }
720 }
721 break;
722 }
724 switch (m_spellInfo->Id)
725 {
726 case 31789: // Righteous Defense (step 1)
727 {
728 if (!unitTarget)
729 return;
730 // not empty (checked), copy
732
733 // remove invalid attackers
734 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
735 if (!(*aItr)->IsValidAttackTarget(m_caster))
736 aItr = attackers.erase(aItr);
737 else
738 ++aItr;
739
740 // selected from list 3
741 uint32 maxTargets = std::min<uint32>(3, attackers.size());
742 for (uint32 i = 0; i < maxTargets; ++i)
743 {
744 Unit::AttackerSet::iterator aItr = attackers.begin();
745 std::advance(aItr, urand(0, attackers.size() - 1));
746 m_caster->CastSpell((*aItr), 31790, true);
747 attackers.erase(aItr);
748 }
749
750 return;
751 }
752 }
753 break;
755 // Hunger for Blood
756 if (m_spellInfo->Id == 51662)
757 {
758 m_caster->CastSpell(m_caster, 63848, true);
759 return;
760 }
761 break;
762 }
763
764 // pet auras
765 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
766 {
767 m_caster->AddPetAura(petSpell);
768 return;
769 }
770
771 // normal DB scripted effect
772 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
774
775 if (gameObjTarget)
776 {
777 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
778 }
779 else if (unitTarget && unitTarget->IsCreature())
780 {
781 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
782 }
783 else if (itemTarget)
784 {
785 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
786 }
787}
ScriptMapMap sSpellScripts
Definition: ObjectMgr.cpp:57
@ UNIT_FIELD_MOUNTDISPLAYID
Definition: UpdateFields.h:126
@ TEMPSUMMON_TIMED_DESPAWN
Definition: Object.h:47
@ SPELLFAMILY_GENERIC
Definition: SharedDefines.h:3528
@ SPELLFAMILY_PALADIN
Definition: SharedDefines.h:3538
@ SPELLFAMILY_ROGUE
Definition: SharedDefines.h:3536
uint8 GetGoAnimProgress() const
Definition: GameObject.h:210
time_t GetRespawnTime() const
Definition: GameObject.h:184
TempSummon * SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0, SummonPropertiesEntry const *properties=nullptr, bool visibleBySummonerOnly=false) const
Definition: Object.cpp:2355
void AddPetAura(PetAura const *petSpell)
Definition: Unit.cpp:17252
std::unordered_set< Unit * > AttackerSet
Definition: Unit.h:632
AttackerSet const & getAttackers() const
Definition: Unit.h:786
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition: MapScripts.cpp:33
Definition: SpellMgr.h:470

References Unit::AddPetAura(), Unit::CastSpell(), effectHandleMode, gameObjTarget, Unit::getAttackers(), GameTime::GetGameTime(), GameObject::GetGoAnimProgress(), WorldObject::GetMap(), GameObject::GetRespawnTime(), Object::GetUInt32Value(), Unit::HasAura(), SpellInfo::Id, Object::IsCreature(), Unit::isMoving(), Object::IsPlayer(), Unit::IsVehicle(), itemTarget, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), GameObject::SendCustomAnim(), GameObject::SetRespawnTime(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sScriptMgr, sSpellMgr, sSpellScripts, WorldObject::SummonCreature(), TEMPSUMMON_TIMED_DESPAWN, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_MOUNTDISPLAYID, unitTarget, and urand().

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5259{
5261 return;
5262
5263 if (!unitTarget)
5264 return;
5265
5266 Player* player = unitTarget->ToPlayer();
5267 if (!player)
5268 {
5269 return;
5270 }
5271
5272 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5273
5274 // -1 means all player equipped items and -2 all items
5275 if (slot < 0)
5276 {
5277 player->DurabilityPointsLossAll(damage, (slot < -1));
5279 return;
5280 }
5281
5282 // invalid slot value
5283 if (slot >= INVENTORY_SLOT_BAG_END)
5284 return;
5285
5286 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5287 {
5288 player->DurabilityPointsLoss(item, damage);
5289 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5290 }
5291}
@ INVENTORY_SLOT_BAG_END
Definition: Player.h:700
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:670
Item * GetItemByPos(uint16 pos) const
Definition: PlayerStorage.cpp:443
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition: Player.cpp:4746
void DurabilityPointsLoss(Item *item, int32 points)
Definition: Player.cpp:4772
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition: Spell.cpp:5129

References damage, Player::DurabilityPointsLoss(), Player::DurabilityPointsLossAll(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDurabilityDamage(), Object::GetEntry(), Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectDurabilityDamagePCT()

void Spell::EffectDurabilityDamagePCT ( SpellEffIndex  effIndex)
5294{
5296 return;
5297
5298 if (!unitTarget)
5299 return;
5300
5301 Player* player = unitTarget->ToPlayer();
5302 if (!player)
5303 {
5304 return;
5305 }
5306
5307 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5308
5309 // FIXME: some spells effects have value -1/-2
5310 // Possibly its mean -1 all player equipped items and -2 all items
5311 if (slot < 0)
5312 {
5313 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5314 return;
5315 }
5316
5317 // invalid slot value
5318 if (slot >= INVENTORY_SLOT_BAG_END)
5319 return;
5320
5321 if (damage <= 0)
5322 return;
5323
5324 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5325 player->DurabilityLoss(item, float(damage) / 100.0f);
5326}
void DurabilityLossAll(double percent, bool inventory)
Definition: Player.cpp:4702
void DurabilityLoss(Item *item, double percent)
Definition: Player.cpp:4728

References damage, Player::DurabilityLoss(), Player::DurabilityLossAll(), effectHandleMode, SpellInfo::Effects, Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantHeldItem()

void Spell::EffectEnchantHeldItem ( SpellEffIndex  effIndex)
4394{
4396 return;
4397
4398 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4399 if (!unitTarget)
4400 return;
4401
4402 Player* item_owner = unitTarget->ToPlayer();
4403 if (!item_owner)
4404 {
4405 return;
4406 }
4407
4409 if (!item)
4410 return;
4411
4412 // must be equipped
4413 if (!item->IsEquipped())
4414 return;
4415
4416 if (m_spellInfo->Effects[effIndex].MiscValue)
4417 {
4418 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4419 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4420 if (!duration)
4421 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4422 if (!duration)
4423 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4424
4425 // Xinef: Venomhide poison, no other spell uses this effect...
4426 if (m_spellInfo->Id == 14792)
4427 duration = 5 * MINUTE * IN_MILLISECONDS;
4428
4429 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4430 if (!pEnchant)
4431 return;
4432
4433 // Always go to temp enchantment slot
4435
4436 // Enchantment will not be applied if a different one already exists
4437 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4438 return;
4439
4440 // Apply the temporary enchantment
4441 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4442 item_owner->ApplyEnchantment(item, slot, true);
4443 }
4444}
@ EQUIPMENT_SLOT_MAINHAND
Definition: Player.h:690
EnchantmentSlot
Definition: Item.h:168
@ TEMP_ENCHANTMENT_SLOT
Definition: Item.h:170
bool IsEquipped() const
Definition: Item.cpp:790
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition: Item.cpp:921
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition: PlayerStorage.cpp:4306
uint32 charges
Definition: DBCStructure.h:1842

References Player::ApplyEnchantment(), SpellItemEnchantmentEntry::charges, damage, effectHandleMode, SpellInfo::Effects, EQUIPMENT_SLOT_MAINHAND, SpellInfo::GetDuration(), Item::GetEnchantmentId(), Object::GetGUID(), Player::GetItemByPos(), SpellInfo::Id, IN_MILLISECONDS, INVENTORY_SLOT_BAG_0, Item::IsEquipped(), m_caster, m_spellInfo, MINUTE, Item::SetEnchantment(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantItemPerm()

void Spell::EffectEnchantItemPerm ( SpellEffIndex  effIndex)
2812{
2814 return;
2815
2816 if (!m_caster->IsPlayer())
2817 return;
2818 if (!itemTarget)
2819 return;
2820
2821 Player* p_caster = m_caster->ToPlayer();
2822
2823 // Handle vellums
2825 {
2826 // destroy one vellum from stack
2827 uint32 count = 1;
2828 p_caster->DestroyItemCount(itemTarget, count, true);
2829 unitTarget = p_caster;
2830 // and add a scroll
2831 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2832 itemTarget = nullptr;
2833 m_targets.SetItemTarget(nullptr);
2834 }
2835 else
2836 {
2837 // do not increase skill if vellum used
2839 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2840
2841 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2842 if (!enchant_id)
2843 return;
2844
2845 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2846 if (!pEnchant)
2847 return;
2848
2849 // item can be in trade slot and have owner diff. from caster
2850 Player* item_owner = itemTarget->GetOwner();
2851 if (!item_owner)
2852 return;
2853
2854 // remove old enchanting before applying new if equipped
2856
2858
2859 // add new enchanting if equipped
2861
2862 item_owner->RemoveTradeableItem(itemTarget);
2864 }
2865}
@ PERM_ENCHANTMENT_SLOT
Definition: Item.h:169
void ClearSoulboundTradeable(Player *currentOwner)
Definition: Item.cpp:1265
void RemoveTradeableItem(Item *item)
Definition: PlayerStorage.cpp:4141
void SetItemTarget(Item *item)
Definition: Spell.cpp:329

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Item::GetTemplate(), ItemTemplate::HasFlag(), SpellInfo::Id, Item::IsArmorVellum(), Object::IsPlayer(), Item::IsWeaponVellum(), ITEM_FLAG_NO_REAGENT_COST, itemTarget, m_caster, m_CastItem, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
2868{
2870 return;
2871
2872 if (!m_caster->IsPlayer())
2873 return;
2874 if (!itemTarget)
2875 return;
2876
2877 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2878 if (!enchant_id)
2879 return;
2880
2881 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2882 if (!pEnchant)
2883 return;
2884
2885 // support only enchantings with add socket in this slot
2886 {
2887 bool add_socket = false;
2888 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2889 {
2890 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2891 {
2892 add_socket = true;
2893 break;
2894 }
2895 }
2896 if (!add_socket)
2897 {
2898 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemPrismatic: attempt apply enchant spell {} with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC ({}) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET ({}), not suppoted yet.",
2900 return;
2901 }
2902 }
2903
2904 // item can be in trade slot and have owner diff. from caster
2905 Player* item_owner = itemTarget->GetOwner();
2906 if (!item_owner)
2907 return;
2908
2909 // remove old enchanting before applying new if equipped
2911
2913
2914 // add new enchanting if equipped
2916
2917 item_owner->RemoveTradeableItem(itemTarget);
2919}

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), SpellInfo::Id, Object::IsPlayer(), ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, itemTarget, LOG_ERROR, m_caster, m_spellInfo, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, PRISMATIC_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, and SpellItemEnchantmentEntry::type.

◆ EffectEnchantItemTmp()

void Spell::EffectEnchantItemTmp ( SpellEffIndex  effIndex)
2922{
2924 return;
2925
2926 if (!m_caster->IsPlayer())
2927 return;
2928
2929 Player* p_caster = m_caster->ToPlayer();
2930
2931 // Rockbiter Weapon apply to both weapon
2932 if (!itemTarget)
2933 return;
2935 {
2936 uint32 spell_id = 0;
2937
2938 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
2939 // Note: damage calculated (correctly) with rounding int32(float(v)) but
2940 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
2941 switch (damage)
2942 {
2943 // Rank 1
2944 case 2:
2945 spell_id = 36744;
2946 break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
2947 // Rank 2
2948 case 4:
2949 spell_id = 36753;
2950 break; // 0% [ 7% == 4, 14% == 4]
2951 case 5:
2952 spell_id = 36751;
2953 break; // 20%
2954 // Rank 3
2955 case 6:
2956 spell_id = 36754;
2957 break; // 0% [ 7% == 6, 14% == 6]
2958 case 7:
2959 spell_id = 36755;
2960 break; // 20%
2961 // Rank 4
2962 case 9:
2963 spell_id = 36761;
2964 break; // 0% [ 7% == 6]
2965 case 10:
2966 spell_id = 36758;
2967 break; // 14%
2968 case 11:
2969 spell_id = 36760;
2970 break; // 20%
2971 default:
2972 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW", damage);
2973 return;
2974 }
2975
2976 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
2977 if (!spellInfo)
2978 {
2979 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
2980 return;
2981 }
2982
2983 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
2984 {
2985 if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j)))
2986 {
2987 if (item->IsFitToSpellRequirements(m_spellInfo))
2988 {
2989 Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
2990 SpellCastTargets targets;
2991 targets.SetItemTarget(item);
2992 spell->prepare(&targets);
2993 }
2994 }
2995 }
2996 return;
2997 }
2998 if (!itemTarget)
2999 return;
3000
3001 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3002
3003 if (!enchant_id)
3004 {
3005 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
3006 return;
3007 }
3008
3009 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3010 if (!pEnchant)
3011 {
3012 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id {} ", m_spellInfo->Id, effIndex, enchant_id);
3013 return;
3014 }
3015
3016 // select enchantment duration
3017 uint32 duration;
3018
3019 // rogue family enchantments exception by duration
3020 if (m_spellInfo->Id == 38615)
3021 duration = 1800; // 30 mins
3022 // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints)
3024 duration = 3600; // 1 hour
3025 // shaman family enchantments
3027 duration = 1800; // 30 mins
3028 // other cases with this SpellVisual already selected
3029 else if (m_spellInfo->SpellVisual[0] == 215)
3030 duration = 1800; // 30 mins
3031 // some fishing pole bonuses except Glow Worm which lasts full hour
3032 else if (m_spellInfo->SpellVisual[0] == 563 && m_spellInfo->Id != 64401)
3033 duration = 600; // 10 mins
3034 // shaman rockbiter enchantments
3035 else if (m_spellInfo->SpellVisual[0] == 0)
3036 duration = 1800; // 30 mins
3037 else if (m_spellInfo->Id == 29702)
3038 duration = 300; // 5 mins
3039 else if (m_spellInfo->Id == 37360)
3040 duration = 300; // 5 mins
3041 // default case
3042 else
3043 duration = 3600; // 1 hour
3044
3045 // item can be in trade slot and have owner diff. from caster
3046 Player* item_owner = itemTarget->GetOwner();
3047 if (!item_owner)
3048 return;
3049
3050 // remove old enchanting before applying new if equipped
3052
3053 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, pEnchant->charges, m_caster->GetGUID());
3054
3055 // add new enchanting if equipped
3057
3058 item_owner->RemoveTradeableItem(itemTarget);
3060}
WeaponAttackType
Definition: Unit.h:208
@ SPELLFAMILY_SHAMAN
Definition: SharedDefines.h:3539
Definition: Spell.h:109
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition: Spell.cpp:3476
std::array< uint32, 2 > SpellVisual
Definition: SpellInfo.h:379

References Player::ApplyEnchantment(), BASE_ATTACK, SpellItemEnchantmentEntry::charges, Item::ClearSoulboundTradeable(), damage, effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Player::GetWeaponForAttack(), SpellInfo::Id, Object::IsPlayer(), itemTarget, LOG_ERROR, m_caster, m_spellInfo, OFF_ATTACK, prepare(), Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellVisual, sSpellItemEnchantmentStore, sSpellMgr, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and TRIGGERED_FULL_MASK.

◆ EffectEnergize()

void Spell::EffectEnergize ( SpellEffIndex  effIndex)
1867{
1869 return;
1870
1871 if (!unitTarget)
1872 return;
1873 if (!unitTarget->IsAlive())
1874 return;
1875
1876 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1877 return;
1878
1879 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1880
1883 return;
1884
1885 if (unitTarget->GetMaxPower(power) == 0)
1886 return;
1887
1888 // Some level depends spells
1889 int level_multiplier = 0;
1890 int level_diff = 0;
1891 switch (m_spellInfo->Id)
1892 {
1893 case 9512: // Restore Energy
1894 level_diff = m_caster->GetLevel() - 40;
1895 level_multiplier = 2;
1896 break;
1897 case 24571: // Blood Fury
1898 level_diff = m_caster->GetLevel() - 60;
1899 level_multiplier = 10;
1900 break;
1901 case 24532: // Burst of Energy
1902 level_diff = m_caster->GetLevel() - 60;
1903 level_multiplier = 4;
1904 break;
1905 case 31930: // Judgements of the Wise
1906 case 63375: // Improved Stormstrike
1907 case 68082: // Glyph of Seal of Command
1909 break;
1910 case 48542: // Revitalize
1912 break;
1913 case 71132: // Glyph of Shadow Word: Pain
1914 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
1915 break;
1916 default:
1917 break;
1918 }
1919
1920 if (level_diff > 0)
1921 damage -= level_multiplier * level_diff;
1922
1923 if (damage < 0)
1924 return;
1925
1927
1928 // Mad Alchemist's Potion
1929 if (m_spellInfo->Id == 45051)
1930 {
1931 // find elixirs on target
1932 bool guardianFound = false;
1933 bool battleFound = false;
1935 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
1936 {
1937 SpellGroupSpecialFlags sFlag = sSpellMgr->GetSpellGroupSpecialFlags(itr->second->GetBase()->GetId());
1938 if (!guardianFound)
1940 guardianFound = true;
1941 if (!battleFound)
1943 battleFound = true;
1944 if (battleFound && guardianFound)
1945 break;
1946 }
1947
1948 // get all available elixirs by mask and spell level
1949 std::set<uint32> availableElixirs;
1950 if (!guardianFound)
1951 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, availableElixirs);
1952 if (!battleFound)
1953 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, availableElixirs);
1954 for (std::set<uint32>::iterator itr = availableElixirs.begin(); itr != availableElixirs.end();)
1955 {
1956 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
1957 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->GetLevel())
1958 availableElixirs.erase(itr++);
1959 else
1960 ++itr;
1961 }
1962
1963 if (!availableElixirs.empty())
1964 {
1965 // cast random elixir on target
1967 }
1968 }
1969}
SpellGroupSpecialFlags
Definition: SpellMgr.h:334
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE
Definition: SpellMgr.h:336
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN
Definition: SpellMgr.h:337
@ SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED
Definition: SharedDefines.h:657
@ SPELLFAMILY_POTION
Definition: SharedDefines.h:3541
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:133
void EnergizeBySpell(Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
Definition: Unit.cpp:11227

References CalculatePct(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetAppliedAuras(), Unit::GetCreateMana(), Unit::GetLevel(), Unit::GetMaxPower(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_CastItem, m_spellInfo, MAX_POWERS, Acore::Containers::SelectRandomContainerElement(), SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, SPELLFAMILY_POTION, SpellInfo::SpellFamilyName, SpellInfo::SpellLevel, sSpellMgr, and unitTarget.

◆ EffectEnergizePct()

void Spell::EffectEnergizePct ( SpellEffIndex  effIndex)
1972{
1974 return;
1975
1976 if (!unitTarget)
1977 return;
1978 if (!unitTarget->IsAlive())
1979 return;
1980
1981 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1982 return;
1983
1984 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1985
1987 return;
1988
1989 uint32 maxPower = unitTarget->GetMaxPower(power);
1990 if (maxPower == 0)
1991 return;
1992
1993 uint32 gain = CalculatePct(maxPower, damage);
1995}

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetMaxPower(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_POWERS, SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectEnvironmentalDMG()

void Spell::EffectEnvironmentalDMG ( SpellEffIndex  effIndex)
303{
305 return;
306
307 if (!unitTarget || !unitTarget->IsAlive())
308 return;
309
310 if (unitTarget->IsPlayer())
312 else
313 {
315
316 uint32 absorb = dmgInfo.GetAbsorb();
317 uint32 resist = dmgInfo.GetResist();
318 uint32 envDamage = dmgInfo.GetDamage();
319
320 Unit::DealDamageMods(unitTarget, envDamage, &absorb);
321 damage = envDamage;
322
324 }
325}
@ DAMAGE_FIRE
Definition: Player.h:839
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition: Player.cpp:754

References damage, DAMAGE_FIRE, Unit::DealDamageMods(), effectHandleMode, Player::EnvironmentalDamage(), DamageInfo::GetAbsorb(), DamageInfo::GetDamage(), DamageInfo::GetResist(), SpellInfo::GetSchoolMask(), Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::SendSpellNonMeleeDamageLog(), SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectFeedPet()

void Spell::EffectFeedPet ( SpellEffIndex  effIndex)
Todo:
: fix crash when a spell has two effects, both pointed at the same item target
4500{
4502 return;
4503
4504 Player* player = m_caster->ToPlayer();
4505 if (!player)
4506 return;
4507
4508 Item* foodItem = itemTarget;
4509 if (!foodItem)
4510 return;
4511
4512 Pet* pet = player->GetPet();
4513 if (!pet)
4514 return;
4515
4516 if (!pet->IsAlive())
4517 return;
4518
4519 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4520 if (benefit <= 0)
4521 return;
4522
4523 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4524
4525 uint32 count = 1;
4526 player->DestroyItemCount(foodItem, count, true);
4528
4529 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4530}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5149

References Unit::CastCustomSpell(), Player::DestroyItemCount(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDestroyItem(), Pet::GetCurrentFoodBenefitLevel(), Object::GetEntry(), Player::GetPet(), Item::GetTemplate(), Unit::IsAlive(), ItemTemplate::ItemLevel, itemTarget, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectForceCast()

void Spell::EffectForceCast ( SpellEffIndex  effIndex)
1001{
1003 return;
1004
1005 if (!unitTarget)
1006 return;
1007
1008 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1009
1010 // normal case
1011 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1012
1013 if (!spellInfo)
1014 {
1015 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1016 return;
1017 }
1018
1019 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1020 {
1021 switch (m_spellInfo->Id)
1022 {
1023 case 52588: // Skeletal Gryphon Escape
1024 case 48598: // Ride Flamebringer Cue
1026 break;
1027 case 52463: // Hide In Mine Car
1028 case 52349: // Overtake
1029 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1030 return;
1031 case 72378: // Blood Nova
1032 case 73058: // Blood Nova
1033 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1034 break;
1035 }
1036 }
1037
1038 CustomSpellValues values;
1039 // set basepoints for trigger with value effect
1041 {
1042 // maybe need to set value only when basepoints == 0?
1046 }
1047
1048 SpellCastTargets targets;
1049 targets.SetUnitTarget(m_caster);
1050
1051 unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
1052}
@ SPELLVALUE_BASE_POINT1
Definition: SpellDefines.h:115
@ SPELLVALUE_BASE_POINT2
Definition: SpellDefines.h:116
@ SPELLVALUE_BASE_POINT0
Definition: SpellDefines.h:114
@ SPELL_EFFECT_FORCE_CAST
Definition: SharedDefines.h:918
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
Definition: SharedDefines.h:919
Definition: SpellDefines.h:163
void AddSpellMod(SpellValueMod mod, int32 value)
Definition: SpellDefines.h:165

References CustomSpellValues::AddSpellMod(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_caster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_FORCE_CAST, SPELL_EFFECT_FORCE_CAST_WITH_VALUE, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectForceDeselect()

void Spell::EffectForceDeselect ( SpellEffIndex  effIndex)
4756{
4758 return;
4759
4760 // xinef: clear focus
4762
4764 data << m_caster->GetGUID();
4765
4767 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4768 Cell::VisitWorldObjects(m_caster, notifier, dist);
4769
4770 // xinef: we should also force pets to remove us from current target
4771 Unit::AttackerSet attackerSet;
4772 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4773 if ((*itr)->IsCreature() && !(*itr)->CanHaveThreatList())
4774 attackerSet.insert(*itr);
4775
4776 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4777 (*itr)->AttackStop();
4778
4779 // Xinef: Mirror images code Initialize Images
4780 if (m_spellInfo->Id == 58836)
4781 {
4782 std::vector<Unit*> images;
4783 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4784 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4785 images.push_back(*itr);
4786
4787 if (images.empty())
4788 return;
4789
4790 UnitList targets;
4791 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4794 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4795 {
4796 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4797 continue;
4798
4799 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4800 {
4801 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4802 {
4803 SpellInfo const* si = spell->GetSpellInfo();
4804 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4805 {
4806 Creature* c = (*iter)->ToCreature();
4807 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4808 continue;
4809 }
4810
4811 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4812 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4813 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4814 {
4815 // at least one effect truly targets an unit, interrupt the spell
4816 interrupt = true;
4817 break;
4818 }
4819
4820 if (interrupt)
4821 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4822 }
4823 }
4824 }
4825 }
4826}
std::list< Unit * > UnitList
Definition: Unit.h:76
#define VISIBILITY_COMPENSATION
Definition: ObjectDefines.h:26
@ TARGET_OBJECT_TYPE_UNIT
Definition: SpellInfo.h:101
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition: SpellInfo.h:102
@ CREATURE_ELITE_WORLDBOSS
Definition: SharedDefines.h:2734
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition: SharedDefines.h:617
@ SMSG_CLEAR_TARGET
Definition: Opcodes.h:989
bool IsDungeonBoss() const
Definition: Creature.cpp:3161
uint32 rank
Definition: CreatureData.h:207
ControlSet m_Controlled
Definition: Unit.h:1793
void SendClearTarget()
Definition: Unit.cpp:20291
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:207
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:193
Definition: GridNotifiers.h:133
Definition: GridNotifiers.h:423
Definition: GridNotifiers.h:861

References CREATURE_ELITE_WORLDBOSS, CURRENT_GENERIC_SPELL, effectHandleMode, SpellInfo::Effects, Unit::getAttackers(), Creature::GetCreatureTemplate(), Object::GetGUID(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Creature::IsDungeonBoss(), Unit::IsPet(), Creature::isWorldBoss(), m_caster, Unit::m_Controlled, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::SendClearTarget(), SMSG_CLEAR_TARGET, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), UNIT_STATE_CASTING, urand(), VISIBILITY_COMPENSATION, Cell::VisitAllObjects(), and Cell::VisitWorldObjects().

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5891{
5893 return;
5894
5895 if (!gameObjTarget)
5896 return;
5897
5898 Unit* caster = m_originalCaster;
5899 if (!caster)
5900 return;
5901
5902 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5904 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5905 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5907}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition: GameObject.cpp:2277
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:9995
Definition: DBCStructure.h:938
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition: DBCStructure.h:950

References damage, effectHandleMode, GAMEOBJECT_FACTION, gameObjTarget, Unit::GetFactionTemplateEntry(), GetSpellInfo(), Object::GetUInt32Value(), FactionTemplateEntry::IsFriendlyTo(), m_originalCaster, GameObject::ModifyHealth(), sFactionTemplateStore, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectGameObjectRepair()

void Spell::EffectGameObjectRepair ( SpellEffIndex  effIndex)

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
5921{
5923 return;
5924
5926 return;
5927
5930}
GameObjectDestructibleState
Definition: SharedDefines.h:1626
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition: GameObject.cpp:2340

References effectHandleMode, SpellInfo::Effects, gameObjTarget, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_originalCaster, m_spellInfo, GameObject::SetDestructibleState(), and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectHeal()

void Spell::EffectHeal ( SpellEffIndex  effIndex)
1461{
1463 return;
1464
1465 if (unitTarget && unitTarget->IsAlive() && damage >= 0)
1466 {
1467 // Try to get original caster
1469
1470 // Skip if m_originalCaster not available
1471 if (!caster)
1472 return;
1473
1474 int32 addhealth = damage;
1475
1476 // Vessel of the Naaru (Vial of the Sunwell trinket)
1477 if (m_spellInfo->Id == 45064)
1478 {
1479 // Amount of heal - depends from stacked Holy Energy
1480 int damageAmount = 0;
1481 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(45062, 0))
1482 {
1483 damageAmount += aurEff->GetAmount();
1485 }
1486
1487 addhealth += damageAmount;
1488 }
1489 // Swiftmend - consumes Regrowth or Rejuvenation
1491 {
1493 // find most short by duration
1494 AuraEffect* forcedTargetAura = nullptr;
1495 AuraEffect* targetAura = nullptr;
1496 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1497 {
1498 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
1499 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
1500 {
1501 if (m_caster->GetGUID() == (*i)->GetCasterGUID())
1502 {
1503 if (!forcedTargetAura || (*i)->GetBase()->GetDuration() < forcedTargetAura->GetBase()->GetDuration())
1504 forcedTargetAura = *i;
1505 }
1506 else if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
1507 targetAura = *i;
1508 }
1509 }
1510
1511 if (forcedTargetAura)
1512 targetAura = forcedTargetAura;
1513
1514 if (!targetAura)
1515 {
1516 LOG_ERROR("spells.effect", "Target({}) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID().ToString());
1517 return;
1518 }
1519
1520 int32 tickheal = targetAura->GetAmount();
1521 if (Unit* auraCaster = targetAura->GetCaster())
1522 tickheal = unitTarget->SpellHealingBonusTaken(auraCaster, targetAura->GetSpellInfo(), tickheal, DOT);
1523
1524 //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
1525 //It is said that talent bonus should not be included
1526
1527 int32 tickcount = 0;
1528 // Rejuvenation
1529 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
1530 tickcount = 4;
1531 // Regrowth
1532 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
1533 tickcount = 6;
1534
1535 addhealth += tickheal * tickcount;
1536
1537 // Glyph of Swiftmend
1538 if (!caster->HasAura(54824))
1539 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
1540
1541 //addhealth += tickheal * tickcount;
1542 //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
1543 }
1544 // Death Pact - return pct of max health to caster
1546 {
1547 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex);
1548 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1549 }
1550 else if (m_spellInfo->Id != 33778) // not lifebloom
1551 {
1552 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex);
1553 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1554 }
1555
1556 // Implemented this way as there is no other way to do it currently (that I know :P)...
1557 if (caster->ToPlayer() && caster->HasAura(23401)) // Nefarian Corrupted Healing (priest)
1558 {
1560 {
1561 m_damage = 0;
1562 caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
1563 return;
1564 }
1565 }
1566
1567 m_damage -= addhealth;
1568 }
1569}
@ DOT
Definition: Unit.h:250
@ SPELL_AURA_PERIODIC_HEAL
Definition: SpellAuraDefines.h:71
@ SPELLFAMILY_DRUID
Definition: SharedDefines.h:3535
@ SPELLFAMILY_DEATHKNIGHT
Definition: SharedDefines.h:3543
@ AURA_STATE_SWIFTMEND
Definition: SharedDefines.h:1307
@ SPELL_SCHOOL_MASK_HOLY
Definition: SharedDefines.h:298
uint32 CountPctFromMaxHealth(int32 pct) const
Definition: Unit.h:878
SpellInfo const * GetSpellInfo() const
Definition: SpellAuraEffects.h:54
uint32 GetId() const
Definition: SpellAuraEffects.cpp:432
Unit * GetCaster() const
Definition: SpellAuraEffects.h:47
Aura * GetBase() const
Definition: SpellAuraEffects.h:49
ObjectGuid GetCasterGUID() const
Definition: SpellAuraEffects.h:48
int32 GetAmount() const
Definition: SpellAuraEffects.h:64
uint32 TargetAuraState
Definition: SpellInfo.h:340

References AURA_STATE_SWIFTMEND, Unit::CastSpell(), Unit::CountPctFromMaxHealth(), damage, DOT, effectHandleMode, AuraEffect::GetAmount(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), AuraEffect::GetCaster(), AuraEffect::GetCasterGUID(), Aura::GetDuration(), Object::GetGUID(), AuraEffect::GetId(), SpellInfo::GetSchoolMask(), AuraEffect::GetSpellInfo(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), HEAL, SpellInfo::Id, Unit::IsAlive(), LOG_ERROR, m_caster, m_damage, m_originalCaster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), Unit::RemoveAurasDueToSpell(), SPELL_AURA_PERIODIC_HEAL, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCHOOL_MASK_HOLY, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), SpellInfo::TargetAuraState, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3663{
3665 return;
3666
3667 if (!unitTarget || !unitTarget->IsAlive())
3668 return;
3669
3670 int32 addhealth = 0;
3671
3672 // damage == 0 - heal for caster max health
3673 if (damage == 0)
3674 addhealth = m_caster->GetMaxHealth();
3675 else
3676 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3677
3678 m_healing += addhealth;
3679}
uint32 GetMaxHealth() const
Definition: Unit.h:870

References damage, effectHandleMode, Unit::GetHealth(), Unit::GetMaxHealth(), Unit::IsAlive(), m_caster, m_healing, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

void Spell::EffectHealPct ( SpellEffIndex  effIndex)

◆ EffectHealthLeech()

void Spell::EffectHealthLeech ( SpellEffIndex  effIndex)
1607{
1609 return;
1610
1611 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1612 return;
1613
1616
1617 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1618
1619 // xinef: handled in spell.cpp
1620 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1621
1622 m_damage += damage;
1623 // get max possible damage, don't count overkill for heal
1624 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1625
1626 //if (m_caster->IsAlive())
1627 //{
1628 // healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
1629 // healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
1630
1631 // m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
1632 //}
1633}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:11747
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:11571

References damage, effectHandleMode, Unit::IsAlive(), LOG_DEBUG, m_caster, m_damage, m_spellInfo, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectInebriate()

void Spell::EffectInebriate ( SpellEffIndex  effIndex)
4464{
4466 return;
4467
4468 if (!unitTarget)
4469 return;
4470
4471 Player* player = unitTarget->ToPlayer();
4472 if (!player)
4473 {
4474 return;
4475 }
4476
4477 uint8 currentDrunk = player->GetDrunkValue();
4478 int32 drunkMod = damage;
4479
4480 if (drunkMod == 0)
4481 return;
4482
4483 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4484 // In addition, we would not want currentDrunk to become more than 100.
4485 // So before adding the values, let's check that everything is fine.
4486 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4487 currentDrunk = 100;
4488 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4489 currentDrunk = 0;
4490 else
4491 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4492
4493 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4494
4495 if (currentDrunk == 100 && roll_chance_i(25))
4496 player->CastSpell(player, 67468, false); // Drunken Vomit
4497}
uint8 GetDrunkValue() const
Definition: Player.h:2153
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition: Player.cpp:971

References Unit::CastSpell(), damage, effectHandleMode, Player::GetDrunkValue(), Object::GetEntry(), m_CastItem, roll_chance_i(), Player::SetDrunkValue(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectInstaKill()

void Spell::EffectInstaKill ( SpellEffIndex  effIndex)
279{
281 return;
282
283 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
284 return;
285
286 if (unitTarget->IsPlayer())
288 return;
289
290 if (m_caster == unitTarget) // prevent interrupt message
291 finish();
292
293 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
294 data << m_caster->GetGUID();
295 data << unitTarget->GetGUID();
296 data << uint32(m_spellInfo->Id);
297 m_caster->SendMessageToSet(&data, true);
298
300}
@ CHEAT_GOD
Definition: Player.h:999
@ SPELL_SCHOOL_MASK_NORMAL
Definition: SharedDefines.h:297
@ SMSG_SPELLINSTAKILLLOG
Definition: Opcodes.h:845
static uint32 DealDamage(Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true, bool allowGM=false, Spell const *spell=nullptr)
Definition: Unit.cpp:810

References CHEAT_GOD, Unit::DealDamage(), effectHandleMode, finish(), Player::GetCommandStatus(), Object::GetGUID(), Unit::GetHealth(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, NODAMAGE, WorldObject::SendMessageToSet(), SMSG_SPELLINSTAKILLLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_SCHOOL_MASK_NORMAL, Object::ToPlayer(), and unitTarget.

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3682{
3684 return;
3685
3686 if (!unitTarget || !unitTarget->IsAlive())
3687 return;
3688
3690 // also exist case: apply cooldown to interrupted cast only and to all spells
3691 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3693 {
3695 {
3696 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3697 // check if we can interrupt spell
3698 if ((spell->getState() == SPELL_STATE_CASTING
3699 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3703 {
3704 if (m_originalCaster)
3705 {
3707 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3708 }
3709 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3711 }
3712 }
3713 }
3714}
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition: Unit.h:543
CurrentSpellTypes
Definition: Unit.h:536
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:539
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:540
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:38
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:30
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4043
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition: Unit.cpp:14810
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition: Unit.h:1455
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition: Spell.cpp:5122
uint32 ChannelInterruptFlags
Definition: SpellInfo.h:354
uint32 InterruptFlags
Definition: SpellInfo.h:352

References Unit::CalcSpellDuration(), CHANNEL_INTERRUPT_FLAG_INTERRUPT, SpellInfo::ChannelInterruptFlags, CURRENT_AUTOREPEAT_SPELL, CURRENT_CHANNELED_SPELL, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_GENERIC_SPELL, effectHandleMode, ExecuteLogEffectInterruptCast(), Unit::GetCurrentSpell(), SpellInfo::GetSchoolMask(), SpellInfo::Id, SpellInfo::InterruptFlags, Unit::InterruptSpell(), Unit::IsAlive(), m_originalCaster, m_spellInfo, Unit::ModSpellDuration(), SpellInfo::PreventionType, Unit::ProhibitSpellSchool(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_PREVENTION_TYPE_SILENCE, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, and unitTarget.

◆ EffectJump()

void Spell::EffectJump ( SpellEffIndex  effIndex)
1074{
1076 return;
1077
1078 if (m_caster->IsInFlight())
1079 return;
1080
1081 if (!unitTarget)
1082 return;
1083
1084 float speedXY, speedZ;
1085 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1086 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1087
1088 if (m_caster->IsPlayer())
1089 {
1090 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1091 }
1092}
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:166
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition: MotionMaster.h:227
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition: SpellEffects.cpp:1157

References CalculateJumpSpeeds(), effectHandleMode, Position::GetExactDist2d(), Unit::GetMotionMaster(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectJumpDest()

void Spell::EffectJumpDest ( SpellEffIndex  effIndex)
1095{
1097 return;
1098
1099 if (m_caster->IsInFlight())
1100 return;
1101
1102 if (!m_targets.HasDst() || m_caster->GetVehicle())
1103 return;
1104
1105 // Init dest coordinates
1106 float x, y, z;
1107 destTarget->GetPosition(x, y, z);
1108 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1109 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1110 return;
1111
1112 float speedXY, speedZ;
1113 float dist = m_caster->GetExactDist2d(x, y);
1114 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1115
1116 // Override, calculations are incorrect
1117 if (m_spellInfo->Id == 49376) // feral charge
1118 {
1119 speedXY = pow(speedZ * 10, 8);
1121
1122 if (Player* player = m_caster->ToPlayer())
1123 {
1124 player->SetCanTeleport(true);
1125 }
1126
1127 if (m_caster->IsPlayer())
1128 {
1129 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1130 }
1131
1132 return;
1133 }
1134
1135 if (m_spellInfo->Id == 57604) // death grip
1136 {
1137 speedZ = 3.0f;
1138 speedXY = 50.0f;
1139 }
1140
1141 // crash fix?
1142 if (speedXY < 1.0f)
1143 speedXY = 1.0f;
1144
1145 if (Player* player = m_caster->ToPlayer())
1146 {
1147 player->SetCanTeleport(true);
1148 }
1149 m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1150
1151 if (m_caster->IsPlayer())
1152 {
1153 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1154 }
1155}
#define INVALID_HEIGHT
Definition: Map.h:165
@ UNIT_FIELD_TARGET
Definition: UpdateFields.h:92
bool IsValidMapCoord(float c)
Definition: GridDefines.h:216
ObjectGuid GetGuidValue(uint16 index) const
Definition: Object.cpp:337

References CalculateJumpSpeeds(), destTarget, effectHandleMode, Position::GetExactDist2d(), Object::GetGuidValue(), Unit::GetMotionMaster(), Position::GetPosition(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), SpellCastTargets::HasDst(), SpellInfo::Id, INVALID_HEIGHT, Unit::IsInFlight(), Object::IsPlayer(), Acore::IsValidMapCoord(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH, sScriptMgr, Object::ToPlayer(), and UNIT_FIELD_TARGET.

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
5683{
5685 return;
5686
5687 if (!unitTarget)
5688 return;
5689
5691 if (!player)
5692 {
5693 return;
5694 }
5695
5696 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5697 if (!creatureEntry)
5698 {
5699 if (m_spellInfo->Id == 42793) // Burn Body
5700 creatureEntry = 24008; // Fallen Combatant
5701 }
5702
5703 if (creatureEntry)
5704 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5705}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition: Player.cpp:12736

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), SpellInfo::Id, m_spellInfo, Player::RewardPlayerAndGroupAtEvent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKillCreditPersonal()

void Spell::EffectKillCreditPersonal ( SpellEffIndex  effIndex)
5669{
5671 return;
5672
5673 if (!unitTarget)
5674 return;
5675
5677 {
5678 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5679 }
5680}

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
4960{
4962 return;
4963
4964 if (!unitTarget)
4965 return;
4966
4967 // Xinef: allow entry specific spells to skip those checks
4968 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
4969 {
4971 return;
4972
4973 if (unitTarget->GetVehicle())
4974 return;
4975
4976 if (Creature* creatureTarget = unitTarget->ToCreature())
4977 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
4978 return;
4979 }
4980
4981 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
4983 return;
4984
4985 // Instantly interrupt non melee spells being casted
4988
4989 float ratio = 0.1f;
4990 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
4991 float speedz = float(damage) * ratio;
4992 if (speedxy <= 0.1f && speedz <= 0.1f)
4993 return;
4994
4995 float x, y;
4996 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
4997 {
4998 if (m_targets.HasDst())
4999 destTarget->GetPosition(x, y);
5000 else
5001 return;
5002 }
5003 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5004 {
5005 m_caster->GetPosition(x, y);
5006 }
5007
5008 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5009
5010 if (unitTarget->IsPlayer())
5011 {
5012 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5013 }
5014}
@ SPELL_EFFECT_KNOCK_BACK_DEST
Definition: SharedDefines.h:922
@ CREATURE_TYPE_GIANT
Definition: SharedDefines.h:2632
@ CREATURE_TYPE_BEAST
Definition: SharedDefines.h:2628
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4110
uint32 GetCreatureType() const
Definition: Unit.cpp:15136
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition: Unit.cpp:19098

References CREATURE_TYPE_BEAST, CREATURE_TYPE_GIANT, damage, destTarget, effectHandleMode, SpellInfo::Effects, Unit::GetCreatureType(), Position::GetPosition(), Unit::GetVehicle(), SpellCastTargets::HasDst(), Unit::HasUnitState(), Unit::InterruptNonMeleeSpells(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsVehicle(), Unit::KnockbackFrom(), m_caster, m_spellInfo, m_targets, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_KNOCK_BACK_DEST, sScriptMgr, TARGET_CHECK_ENTRY, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_ROOT, and unitTarget.

◆ EffectLeap()

void Spell::EffectLeap ( SpellEffIndex  effIndex)
4686{
4688 return;
4689
4690 if (!unitTarget || unitTarget->IsInFlight())
4691 return;
4692
4693 if (!m_targets.HasDst())
4694 return;
4695
4696 Position dstpos = destTarget->GetPosition();
4698}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition: Unit.cpp:19946

References destTarget, effectHandleMode, Position::GetOrientation(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellCastTargets::HasDst(), Unit::IsInFlight(), m_caster, m_targets, Unit::NearTeleportTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectLeapBack()

void Spell::EffectLeapBack ( SpellEffIndex  effIndex)
5017{
5019 return;
5020
5021 if (!unitTarget)
5022 return;
5023
5024 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5025 float speedz = damage / 10.0f;
5026 //1891: Disengage
5028
5029 if (m_caster->IsPlayer())
5030 {
5031 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5032 }
5033
5034 // xinef: changes fall time
5035 if (m_caster->IsPlayer())
5037}
@ SPELLFAMILY_HUNTER
Definition: SharedDefines.h:3537
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition: Unit.cpp:19479

References damage, effectHandleMode, SpellInfo::Effects, GameTime::GetGameTime(), Position::GetPositionZ(), Object::IsPlayer(), Unit::JumpTo(), m_caster, m_spellInfo, Player::SetFallInformation(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3233{
3235 return;
3236
3237 if (!unitTarget)
3238 return;
3239
3240 if (unitTarget->ToPlayer())
3241 {
3242 EffectLearnSpell(effIndex);
3243 return;
3244 }
3245 Pet* pet = unitTarget->ToPet();
3246 if (!pet)
3247 return;
3248
3249 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3250 if (!learn_spellproto)
3251 return;
3252
3253 pet->learnSpell(learn_spellproto->Id);
3255 pet->GetOwner()->PetSpellInitialize();
3256}
bool learnSpell(uint32 spell_id)
Definition: Pet.cpp:1912
void EffectLearnSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:2519

References effectHandleMode, EffectLearnSpell(), SpellInfo::Effects, Pet::GetOwner(), SpellInfo::Id, Pet::learnSpell(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellMgr, Unit::ToPet(), Object::ToPlayer(), and unitTarget.

Referenced by EffectLearnSpell().

◆ EffectLearnSkill()

void Spell::EffectLearnSkill ( SpellEffIndex  effIndex)
2750{
2752 return;
2753
2754 if (!unitTarget->IsPlayer())
2755 return;
2756
2757 if (damage < 0)
2758 return;
2759
2760 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2761 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2762 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2763}
uint16 GetPureSkillValue(uint32 skill) const
Definition: Player.cpp:5502
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition: Player.cpp:5316

References damage, effectHandleMode, SpellInfo::Effects, Player::GetPureSkillValue(), Object::IsPlayer(), m_spellInfo, Player::SetSkill(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectLearnSpell()

void Spell::EffectLearnSpell ( SpellEffIndex  effIndex)
2520{
2522 return;
2523
2524 if (!unitTarget)
2525 return;
2526
2527 if (!unitTarget->IsPlayer())
2528 {
2529 if (unitTarget->ToPet())
2530 EffectLearnPetSpell(effIndex);
2531 return;
2532 }
2533
2534 Player* player = unitTarget->ToPlayer();
2535
2536 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2537 player->learnSpell(spellToLearn);
2538
2539 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2540 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2541}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition: Player.cpp:3271
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:3232

References damage, effectHandleMode, EffectLearnPetSpell(), SpellInfo::Effects, Object::GetGUID(), SpellInfo::Id, Object::IsPlayer(), Player::learnSpell(), LOG_DEBUG, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5496{
5498 return;
5499
5500 if (!m_caster->IsPlayer())
5501 return;
5502
5503 Player* p_caster = m_caster->ToPlayer();
5505 return;
5506
5507 if (itemTarget->GetCount() < 5)
5508 return;
5509
5510 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5511 {
5512 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5513 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5514 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5515 }
5516
5518}
@ LOOT_MILLING
Definition: LootMgr.h:88
@ CONFIG_SKILL_MILLING
Definition: IWorld.h:97
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition: Player.cpp:7773
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition: PlayerUpdates.cpp:719

References CONFIG_SKILL_MILLING, effectHandleMode, Item::GetCount(), Object::GetGUID(), Player::GetPureSkillValue(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_IS_MILLABLE, itemTarget, LOOT_MILLING, m_caster, ItemTemplate::RequiredSkillRank, Player::SendLoot(), SKILL_INSCRIPTION, SPELL_EFFECT_HANDLE_HIT_TARGET, sWorld, Object::ToPlayer(), and Player::UpdateGatherSkill().

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5329{
5331 return;
5332
5333 if (!unitTarget)
5334 return;
5335
5337}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition: ThreatMgr.cpp:508
ThreatMgr & GetThreatMgr()
Definition: Unit.h:839

References damage, effectHandleMode, Unit::GetThreatMgr(), m_caster, ThreatMgr::ModifyThreatByPercent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectNULL()

void Spell::EffectNULL ( SpellEffIndex  effIndex)
243{
244 LOG_DEBUG("spells.aura", "WORLD: Spell Effect DUMMY");
245}

References LOG_DEBUG.

Referenced by EffectPull().

◆ EffectOpenLock()

void Spell::EffectOpenLock ( SpellEffIndex  effIndex)
Todo:
: Add script for spell 41920 - Filling, becouse server it freze when use this spell
2064{
2066 return;
2067
2068 if (!m_caster->IsPlayer())
2069 {
2070 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2071 return;
2072 }
2073
2074 Player* player = m_caster->ToPlayer();
2075
2076 uint32 lockId = 0;
2077 ObjectGuid guid;
2078
2079 // Get lockId
2080 if (gameObjTarget)
2081 {
2082 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2083 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2084 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2085 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2086 {
2087 //CanUseBattlegroundObject() already called in CheckCast()
2088 // in battleground check
2089 if (Battleground* bg = player->GetBattleground())
2090 {
2091 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2092 return;
2093 }
2094 }
2095 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2096 {
2097 //CanUseBattlegroundObject() already called in CheckCast()
2098 // in battleground check
2099 if (Battleground* bg = player->GetBattleground())
2100 {
2101 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2102 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2103 return;
2104 }
2105 }
2106 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2107 {
2110 {
2112 }
2113 return;
2114 }
2116 // handle outdoor pvp object opening, return true if go was registered for handling
2117 // these objects must have been spawned by outdoorpvp!
2118 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2119 return;
2120 lockId = goInfo->GetLockId();
2121 guid = gameObjTarget->GetGUID();
2122 }
2123 else if (itemTarget)
2124 {
2125 lockId = itemTarget->GetTemplate()->LockID;
2126 guid = itemTarget->GetGUID();
2127 }
2128 else
2129 {
2130 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2131 return;
2132 }
2133
2134 SkillType skillId = SKILL_NONE;
2135 int32 reqSkillValue = 0;
2136 int32 skillValue;
2137
2138 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2139 if (res != SPELL_CAST_OK)
2140 {
2141 SendCastResult(res);
2142 return;
2143 }
2144
2145 if (gameObjTarget)
2146 SendLoot(guid, LOOT_SKINNING);
2147 else if (itemTarget)
2148 {
2150 if (Player* itemOwner = itemTarget->GetOwner())
2151 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2152 }
2153
2154 // not allow use skill grow at item base open
2155 if (!m_CastItem && skillId != SKILL_NONE)
2156 {
2157 // update skill if really known
2158 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2159 {
2160 if (gameObjTarget)
2161 {
2162 // Allow one skill-up until respawned
2163 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2164 {
2166 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2167 }
2168
2169 }
2170 else if (itemTarget)
2171 {
2172 // Do one skill-up
2173 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2174 }
2175 }
2176 }
2178}
#define sOutdoorPvPMgr
Definition: OutdoorPvPMgr.h:103
@ LOOT_SKINNING
Definition: LootMgr.h:86
@ ITEM_FIELD_FLAGS
Definition: UpdateFields.h:42
@ GO_JUST_DEACTIVATED
Definition: GameObject.h:114
@ ITEM_FIELD_FLAG_UNLOCKED
Definition: ItemTemplate.h:111
@ ITEM_CHANGED
Definition: Item.h:210
@ GAMEOBJECT_TYPE_BUTTON
Definition: SharedDefines.h:1561
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition: SharedDefines.h:1584
@ GAMEOBJECT_TYPE_GOOBER
Definition: SharedDefines.h:1570
@ BATTLEGROUND_EY
Definition: SharedDefines.h:3487
Unit * GetOwner() const
Definition: GameObject.cpp:1238
void AddToSkillupList(ObjectGuid playerGuid)
Definition: GameObject.cpp:3068
bool IsInSkillupList(ObjectGuid playerGuid) const
Definition: GameObject.cpp:3074
LootState getLootState() const
Definition: GameObject.h:225
void SetLootState(LootState s, Unit *unit=nullptr)
Definition: GameObject.cpp:2442
Definition: GameObjectData.h:31
uint32 GetAutoCloseTime() const
Definition: GameObjectData.h:510
uint32 noDamageImmune
Definition: GameObjectData.h:48
struct GameObjectTemplate::@227::@230 button
uint32 losOK
Definition: GameObjectData.h:64
struct GameObjectTemplate::@227::@238 goober
uint32 GetLockId() const
Definition: GameObjectData.h:427
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition: Item.cpp:715
Definition: Object.h:100
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition: Spell.cpp:5137
void SendLoot(ObjectGuid guid, LootType loottype)
Definition: SpellEffects.cpp:1997

References GameObject::AddToSkillupList(), BATTLEGROUND_EY, GameObjectTemplate::button, CanOpenLock(), effectHandleMode, ExecuteLogEffectOpenLock(), GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_FLAGSTAND, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_TRAP, gameObjTarget, GameObjectTemplate::GetAutoCloseTime(), Player::GetBattleground(), GameObject::GetGOInfo(), Object::GetGUID(), GameObjectTemplate::GetLockId(), GameObject::getLootState(), GameObject::GetOwner(), Item::GetOwner(), Player::GetPureSkillValue(), Item::GetTemplate(), GO_JUST_DEACTIVATED, GameObjectTemplate::goober, SpellInfo::Id, IN_MILLISECONDS, GameObject::IsInSkillupList(), Object::IsPlayer(), ITEM_CHANGED, ITEM_FIELD_FLAG_UNLOCKED, ITEM_FIELD_FLAGS, itemTarget, ItemTemplate::LockID, LOG_DEBUG, LOOT_SKINNING, GameObjectTemplate::losOK, m_caster, m_CastItem, m_spellInfo, GameObjectTemplate::noDamageImmune, SendCastResult(), SendLoot(), Object::SetFlag(), GameObject::SetLootState(), GameObject::SetRespawnTime(), Item::SetState(), SKILL_NONE, sOutdoorPvPMgr, SPELL_CAST_OK, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), GameObjectTemplate::type, and Player::UpdateGatherSkill().

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4668{
4670 return;
4671
4672 if (m_caster->IsPlayer())
4673 m_caster->ToPlayer()->SetCanParry(true);
4674}
void SetCanParry(bool value)
Definition: Player.cpp:13127

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanParry(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1833{
1835 return;
1836
1837 if (!m_spellAura)
1838 {
1840 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1841
1842 // Caster not in world, might be spell triggered from aura removal
1843 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1844 return;
1845 DynamicObject* dynObj = new DynamicObject(false);
1846 if (!dynObj->CreateDynamicObject(caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
1847 {
1848 delete dynObj;
1849 return;
1850 }
1851
1853 {
1854 m_spellAura = aura;
1857 }
1858 else
1859 return;
1860 }
1861
1864}
@ DYNAMIC_OBJECT_AREA_SPELL
Definition: DynamicObject.h:30
#define MAX_EFFECT_MASK
Definition: DBCStructure.h:1637
DynamicObject * GetDynobjOwner() const
Definition: SpellAuras.h:109
static Aura * TryCreate(SpellInfo const *spellproto, uint8 effMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemGUID=ObjectGuid::Empty)
Definition: SpellAuras.cpp:352

References Aura::_ApplyEffectForTargets(), Aura::_RegisterForTargets(), ASSERT, DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_AREA_SPELL, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, WorldObject::FindMap(), Map::GenerateLowGuid(), Aura::GetDynobjOwner(), Object::GetEntry(), Object::GetGUID(), WorldObject::GetMap(), ObjectAccessor::GetUnit(), SpellInfo::Id, Object::IsInWorld(), m_caster, m_originalCaster, m_spellAura, m_spellInfo, m_spellValue, m_triggeredByAuraSpell, MAX_EFFECT_MASK, Aura::SetTriggeredByAuraSpellInfo(), SPELL_EFFECT_HANDLE_HIT, TriggeredByAuraSpellData::spellInfo, Aura::TryCreate(), and WORLD_TRIGGER.

◆ EffectPickPocket()

void Spell::EffectPickPocket ( SpellEffIndex  effIndex)

◆ EffectPlayMusic()

void Spell::EffectPlayMusic ( SpellEffIndex  effIndex)
6082{
6084 return;
6085
6086 if (!unitTarget)
6087 return;
6088
6089 Player* player = unitTarget->ToPlayer();
6090 if (!player)
6091 {
6092 return;
6093 }
6094
6095 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6096
6097 if (!sSoundEntriesStore.LookupEntry(soundid))
6098 {
6099 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6100 return;
6101 }
6102
6104}
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
Definition: MiscPackets.h:58

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_spellInfo, Player::SendDirectMessage(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPlaySound()

void Spell::EffectPlaySound ( SpellEffIndex  effIndex)
6135{
6137 return;
6138
6139 if (!unitTarget)
6140 return;
6141
6142 Player* player = unitTarget->ToPlayer();
6143 if (!player)
6144 {
6145 return;
6146 }
6147
6148 switch (m_spellInfo->Id)
6149 {
6150 case 58730: // Restricted Flight Area
6151 case 58600: // Restricted Flight Area
6153 break;
6154 default:
6155 break;
6156 }
6157
6158 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6159
6160 if (!sSoundEntriesStore.LookupEntry(soundId))
6161 {
6162 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6163 return;
6164 }
6165
6166 player->PlayDirectSound(soundId, player);
6167}
@ LANG_ZONE_NOFLYZONE
Definition: Language.h:753
Definition: Chat.h:39
void SendNotification(std::string_view str)
Definition: Chat.cpp:107
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition: Object.cpp:2892

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), SpellInfo::Id, LANG_ZONE_NOFLYZONE, LOG_ERROR, m_spellInfo, WorldObject::PlayDirectSound(), ChatHandler::SendNotification(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPowerBurn()

void Spell::EffectPowerBurn ( SpellEffIndex  effIndex)
1419{
1421 return;
1422
1423 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1424 return;
1425
1426 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1427
1429 return;
1430
1431 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1432 if (m_spellInfo->Id == 8129)
1433 {
1436 damage = std::min(damage, maxDamage);
1437
1438 // Remove fear
1440 }
1441
1442 int32 power = damage;
1443 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1444 if (PowerType == POWER_MANA)
1445 power -= unitTarget->GetSpellCritDamageReduction(power);
1446
1447 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1448
1449 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1450 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1451
1452 // add log data before multiplication (need power amount, not damage)
1453 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1454
1455 newDamage = int32(newDamage * dmgMultiplier);
1456
1457 m_damage += newDamage;
1458}
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:14105
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition: Unit.h:1034
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition: Spell.cpp:5106

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectTakeTargetPower(), Unit::GetMaxPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_damage, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, Unit::RemoveAurasByType(), SPELL_AURA_MOD_FEAR, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectPowerDrain()

void Spell::EffectPowerDrain ( SpellEffIndex  effIndex)
1340{
1342 return;
1343
1344 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1345 return;
1346
1347 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1348
1350 return;
1351
1352 // add spell damage bonus
1355
1356 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1357 int32 power = damage;
1358 if (PowerType == POWER_MANA)
1359 power -= unitTarget->GetSpellCritDamageReduction(power);
1360
1361 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1362
1363 float gainMultiplier = 0.0f;
1364
1365 // Don`t restore from self drain
1366 if (m_caster != unitTarget)
1367 {
1368 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1369
1370 int32 gain = int32(newDamage * gainMultiplier);
1371
1373 }
1374 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1375}

References damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), ExecuteLogEffectTakeTargetPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectProficiency()

void Spell::EffectProficiency ( SpellEffIndex  effIndex)
2290{
2292 return;
2293
2294 if (!m_caster->IsPlayer())
2295 return;
2296 Player* p_target = m_caster->ToPlayer();
2297
2299 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2300 {
2301 p_target->AddWeaponProficiency(subClassMask);
2303 }
2304 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2305 {
2306 p_target->AddArmorProficiency(subClassMask);
2308 }
2309}
uint32 GetArmorProficiency() const
Definition: Player.h:1355
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition: Player.cpp:10101
uint32 GetWeaponProficiency() const
Definition: Player.h:1354
void AddArmorProficiency(uint32 newflag)
Definition: Player.h:1353
void AddWeaponProficiency(uint32 newflag)
Definition: Player.h:1352
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:376

References Player::AddArmorProficiency(), Player::AddWeaponProficiency(), effectHandleMode, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::GetArmorProficiency(), Player::GetWeaponProficiency(), Object::IsPlayer(), ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON, m_caster, m_spellInfo, Player::SendProficiency(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

void Spell::EffectPull ( SpellEffIndex  effIndex)
Todo:
: create a proper pull towards distract spell center for distract
2662{
2664 EffectNULL(effIndex);
2665}
void EffectNULL(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:242

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5102{
5104 return;
5105
5106 if (!unitTarget)
5107 return;
5108
5109 Position pos;
5110 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5111 {
5112 if (m_targets.HasDst())
5113 pos.Relocate(*destTarget);
5114 else
5115 return;
5116 }
5117 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5118 {
5119 // Xinef: Increase Z position a little bit, should protect from falling through textures
5121 }
5122
5123 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5124 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5125
5126 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5127
5128 if (unitTarget->IsPlayer())
5129 {
5130 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5131 }
5132}
@ SPELL_EFFECT_PULL_TOWARDS_DEST
Definition: SharedDefines.h:923
double gravity
Definition: MovementUtil.cpp:24
void Relocate(float x, float y)
Definition: Position.h:73

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetDistance(), Unit::GetMotionMaster(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Movement::gravity, SpellCastTargets::HasDst(), Object::IsPlayer(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), Position::Relocate(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_PULL_TOWARDS_DEST, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectQuestClear()

void Spell::EffectQuestClear ( SpellEffIndex  effIndex)
5040{
5042 return;
5043
5044 if (!unitTarget)
5045 return;
5046
5047 Player* player = unitTarget->ToPlayer();
5048 if (!player)
5049 {
5050 return;
5051 }
5052
5053 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5054
5055 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5056
5057 if (!quest)
5058 return;
5059
5060 // Player has never done this quest
5061 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5062 return;
5063
5064 // remove all quest entries for 'entry' from quest log
5065 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5066 {
5067 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5068 if (logQuest == quest_id)
5069 {
5070 player->SetQuestSlot(slot, 0);
5071
5072 // we ignore unequippable quest items in this case, it's still be equipped
5073 player->TakeQuestSourceItem(logQuest, false);
5074
5075 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5076 {
5077 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5078 player->UpdatePvPState();
5079 }
5080 }
5081 }
5082
5083 player->RemoveRewardedQuest(quest_id);
5084 player->RemoveActiveQuest(quest_id, false);
5085}
@ QUEST_FLAGS_FLAGS_PVP
Definition: QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:33
@ QUEST_STATUS_NONE
Definition: QuestDef.h:100
bool IsHostile
Definition: Player.h:360
bool IsInHostileArea
Definition: Player.h:361
bool HasPvPForcingQuest() const
Definition: PlayerQuest.cpp:2489
void UpdatePvPState()
Definition: PlayerUpdates.cpp:1390
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition: Player.h:1476
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition: Player.h:1480
PvPInfo pvpInfo
Definition: Player.h:1829
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition: PlayerQuest.cpp:1357
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1489
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: PlayerQuest.cpp:1424
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1507
Definition: QuestDef.h:210
bool HasFlag(uint32 flag) const
Definition: QuestDef.h:221

References effectHandleMode, SpellInfo::Effects, Player::GetQuestSlotQuestId(), Player::GetQuestStatus(), Quest::HasFlag(), Player::HasPvPForcingQuest(), PvPInfo::IsHostile, PvPInfo::IsInHostileArea, m_spellInfo, MAX_QUEST_LOG_SIZE, Player::pvpInfo, QUEST_FLAGS_FLAGS_PVP, QUEST_STATUS_NONE, Player::RemoveActiveQuest(), Player::RemoveRewardedQuest(), Player::SetQuestSlot(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Player::TakeQuestSourceItem(), Object::ToPlayer(), unitTarget, and Player::UpdatePvPState().

◆ EffectQuestComplete()

void Spell::EffectQuestComplete ( SpellEffIndex  effIndex)
4727{
4729 return;
4730
4731 if (!unitTarget)
4732 return;
4733
4734 Player* player = unitTarget->ToPlayer();
4735 if (!player)
4736 {
4737 return;
4738 }
4739
4740 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4741 if (questId)
4742 {
4743 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4744 if (!quest)
4745 return;
4746
4747 uint16 logSlot = player->FindQuestSlot(questId);
4748 if (logSlot < MAX_QUEST_LOG_SIZE)
4749 player->AreaExploredOrEventHappens(questId);
4750 else if (player->CanTakeQuest(quest, false)) // never rewarded before
4751 player->CompleteQuest(questId); // quest not in log - for internal use
4752 }
4753}
uint16 FindQuestSlot(uint32 quest_id) const
Definition: PlayerQuest.cpp:1776
bool CanTakeQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:251
void CompleteQuest(uint32 quest_id)
Definition: PlayerQuest.cpp:597
void AreaExploredOrEventHappens(uint32 questId)
Definition: PlayerQuest.cpp:1785

References Player::AreaExploredOrEventHappens(), Player::CanTakeQuest(), Player::CompleteQuest(), effectHandleMode, SpellInfo::Effects, Player::FindQuestSlot(), m_spellInfo, MAX_QUEST_LOG_SIZE, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestFail()

void Spell::EffectQuestFail ( SpellEffIndex  effIndex)
5708{
5710 return;
5711
5712 if (!unitTarget)
5713 return;
5714
5715 if (Player* player = unitTarget->ToPlayer())
5716 {
5717 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5718 }
5719}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5722{
5724 return;
5725
5726 if (!unitTarget)
5727 return;
5728
5729 Player* player = unitTarget->ToPlayer();
5730 if (!player)
5731 return;
5732
5733 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5734 {
5735 if (!player->CanTakeQuest(quest, false))
5736 return;
5737
5738 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5739 player->AddQuestAndCheckCompletion(quest, player);
5740
5741 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5742 }
5743}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition: GossipDef.cpp:388
bool CanAddQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:264
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition: PlayerQuest.cpp:420
PlayerMenu * PlayerTalkClass
Definition: Player.h:2221

References Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), m_spellInfo, Player::PlayerTalkClass, PlayerMenu::SendQuestGiverQuestDetails(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectRechargeManaGem()

void Spell::EffectRechargeManaGem ( SpellEffIndex  effIndex)
6224{
6226 return;
6227
6228 if (!unitTarget || !unitTarget->IsPlayer())
6229 return;
6230
6231 Player* player = m_caster->ToPlayer();
6232
6233 if (!player)
6234 return;
6235
6236 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6237
6238 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6239 if (!pProto)
6240 {
6241 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6242 return;
6243 }
6244
6245 if (Item* pItem = player->GetItemByEntry(item_id))
6246 {
6247 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6248 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6249 pItem->SetState(ITEM_CHANGED, player);
6250 }
6251}

References EFFECT_0, effectHandleMode, SpellInfo::Effects, EQUIP_ERR_ITEM_NOT_FOUND, Player::GetItemByEntry(), Object::IsPlayer(), ITEM_CHANGED, m_caster, m_spellInfo, MAX_ITEM_PROTO_SPELLS, Player::SendEquipError(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, _Spell::SpellCharges, ItemTemplate::Spells, Object::ToPlayer(), and unitTarget.

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5882{
5884 return;
5885
5886 if (unitTarget)
5888}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition: Unit.h:846

References damage, effectHandleMode, Object::GetGUID(), m_caster, Unit::SetRedirectThreat(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6170{
6172 return;
6173
6174 if (!unitTarget)
6175 return;
6176 // there may be need of specifying casterguid of removed auras
6177 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6178}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, Unit::RemoveAurasDueToSpell(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6070{
6072 return;
6073
6074 if (!unitTarget || !unitTarget->IsCreature() ||
6076 return;
6077
6079}
@ UNIT_CAN_BE_RENAMED
Definition: UnitDefines.h:128
@ UNIT_FIELD_BYTES_2
Definition: UpdateFields.h:161
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:911
PetType getPetType() const
Definition: Pet.h:52

References effectHandleMode, Pet::getPetType(), HUNTER_PET, Object::IsCreature(), Unit::IsPet(), Object::SetByteFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), UNIT_CAN_BE_RENAMED, UNIT_FIELD_BYTES_2, and unitTarget.

◆ EffectReputation()

void Spell::EffectReputation ( SpellEffIndex  effIndex)
4701{
4703 return;
4704
4705 if (!unitTarget)
4706 return;
4707
4708 Player* player = unitTarget->ToPlayer();
4709 if (!player)
4710 {
4711 return;
4712 }
4713
4714 float repChange = static_cast<float>(damage);
4715
4716 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4717
4718 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4719 if (!factionEntry)
4720 return;
4721
4722 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4723 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4724}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
@ REPUTATION_SOURCE_SPELL
Definition: Player.h:245
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus=false)
Definition: Player.cpp:5869
ReputationMgr & GetReputationMgr()
Definition: Player.h:2107
bool ModifyReputation(FactionEntry const *factionEntry, float standing, bool noSpillOver=false, Optional< ReputationRank > repMaxCap={})
Definition: ReputationMgr.h:118
Definition: DBCStructure.h:906

References Player::CalculateReputationGain(), damage, effectHandleMode, SpellInfo::Effects, Player::GetReputationMgr(), m_spellInfo, ReputationMgr::ModifyReputation(), REPUTATION_SOURCE_SPELL, sFactionStore, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrect()

void Spell::EffectResurrect ( SpellEffIndex  effIndex)
4619{
4621 return;
4622
4623 if (!unitTarget)
4624 return;
4625
4626 if (!unitTarget)
4627 return;
4628
4629 Player* target = unitTarget->ToPlayer();
4630 if (!target)
4631 {
4632 return;
4633 }
4634
4635 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4636 return;
4637
4638 if (target->isResurrectRequested()) // already have one active request
4639 return;
4640
4641 uint32 health = target->CountPctFromMaxHealth(damage);
4643
4644 ExecuteLogEffectResurrect(effIndex, target);
4645
4647 SendResurrectRequest(target);
4648}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition: Player.h:1798
bool isResurrectRequested() const
Definition: Player.h:1810
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition: Spell.cpp:5167
void SendResurrectRequest(Player *target)
Definition: Spell.cpp:5229

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, ExecuteLogEffectResurrect(), Object::GetGUID(), WorldLocation::GetMapId(), Unit::GetMaxPower(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Object::IsInWorld(), Player::isResurrectRequested(), m_caster, POWER_MANA, SendResurrectRequest(), Player::setResurrectRequestData(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrectNew()

◆ EffectResurrectPet()

void Spell::EffectResurrectPet ( SpellEffIndex  effIndex)
Todo:
: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
5178{
5180 return;
5181
5182 if (damage < 0)
5183 return;
5184
5185 Player* player = m_caster->ToPlayer();
5186 if (!player)
5187 {
5188 return;
5189 }
5190
5191 Pet* pet = player->GetPet();
5192 if (!pet)
5193 {
5194 // Position passed to SummonPet is irrelevant with current implementation,
5195 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5196 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0s, damage);
5197 return;
5198 }
5199
5201 if (pet->IsAlive())
5202 {
5203 return;
5204 }
5205
5206 // Reposition the pet's corpse before reviving so as not to grab aggro
5207 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5208 float x, y, z; // Will be used later to reposition the pet if we have one
5209 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5210 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5211 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5214 pet->setDeathState(DeathState::Alive);
5215 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5217 pet->SetDisplayId(pet->GetNativeDisplayId());
5218
5219 // xinef: restore movement
5220 if (auto ci = pet->GetCharmInfo())
5221 {
5222 ci->SetIsAtStay(false);
5223 ci->SetIsFollowing(false);
5224 }
5225
5227}
@ UNIT_STATE_POSSESSED
Definition: UnitDefines.h:165
@ UNIT_STATE_ALL_STATE
Definition: UnitDefines.h:199
#define PET_FOLLOW_DIST
Definition: PetDefines.h:198
@ SUMMON_PET
Definition: PetDefines.h:31
@ UNIT_DYNFLAG_NONE
Definition: SharedDefines.h:3120
float GetFollowAngle() const override
Definition: TemporarySummon.h:82
bool GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0, WorldObject const *forWho=nullptr, bool force=false) const
Definition: Object.cpp:2699
void setDeathState(DeathState s, bool despawn=false) override
A creature can be in 4 different states: Alive, JustDied, Corpse, and JustRespawned....
Definition: Pet.cpp:631
void SetDisplayId(uint32 modelId, float displayScale=1.f) override
Definition: Pet.cpp:2421
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0s, uint32 healthPct=0)
Definition: Player.cpp:8929
void ReplaceAllDynamicFlags(uint32 flag) override
Definition: Unit.h:700
void SetHealth(uint32 val)
Definition: Unit.cpp:15432
uint32 GetNativeDisplayId() const
Definition: Unit.h:1523
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition: Unit.h:684

References Unit::ClearUnitState(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, Unit::GetCharmInfo(), WorldObject::GetClosePoint(), Unit::GetCombatReach(), Minion::GetFollowAngle(), Unit::GetNativeDisplayId(), Position::GetOrientation(), Player::GetPet(), Unit::IsAlive(), m_caster, Unit::NearTeleportTo(), PET_FOLLOW_DIST, PET_SAVE_AS_CURRENT, Position::Relocate(), Unit::RemoveUnitFlag(), Unit::ReplaceAllDynamicFlags(), Pet::SavePetToDB(), Pet::setDeathState(), Pet::SetDisplayId(), Unit::SetHealth(), SPELL_EFFECT_HANDLE_HIT, SUMMON_PET, Player::SummonPet(), Object::ToPlayer(), UNIT_DYNFLAG_NONE, UNIT_FLAG_SKINNABLE, UNIT_STATE_ALL_STATE, and UNIT_STATE_POSSESSED.

◆ EffectSanctuary()

void Spell::EffectSanctuary ( SpellEffIndex  effIndex)
4003{
4005 return;
4006
4007 if (!unitTarget)
4008 return;
4009
4011 {
4013 // Xinef: replaced with CombatStop(false)
4016
4017 // Night Elf: Shadowmeld only resets threat temporarily
4018 if (m_spellInfo->Id != 59646)
4020
4021 if (unitTarget->IsPlayer())
4022 unitTarget->ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
4023 }
4024 else
4025 {
4026 unitTarget->getHostileRefMgr().UpdateVisibility(m_spellInfo->Id == 59646); // Night Elf: Shadowmeld
4027 unitTarget->CombatStop(true);
4028 }
4029
4030 UnitList targets;
4031 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4034 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4035 {
4036 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4037 continue;
4038
4040 {
4041 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4042 {
4043 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4044 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4045 {
4046 Creature* c = (*iter)->ToCreature();
4047 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4048 continue;
4049 }
4050 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4051 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4052 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4053 {
4054 // at least one effect truly targets an unit, interrupt the spell
4055 interrupt = true;
4056 break;
4057 }
4058 if (interrupt)
4059 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4060 }
4061 }
4062 }
4063
4064 // Xinef: Set last sanctuary time
4066}
#define CURRENT_MAX_SPELL
Definition: Unit.h:544
void UpdateVisibility(bool checkThreat)
Definition: HostileRefMgr.cpp:236
void addThreatPercent(int32 percent)
Definition: HostileRefMgr.cpp:85
void SendAttackSwingCancelAttack()
Definition: PlayerMisc.cpp:140
void CombatStop(bool includingCast=false)
Definition: Unit.cpp:10397
void RemoveAllAttackers()
Remove all units in m_attackers list and send them AttackStop()
Definition: Unit.cpp:10445
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition: Unit.cpp:10364
virtual bool IsEncounterInProgress() const
Definition: InstanceScript.cpp:122

References HostileRefMgr::addThreatPercent(), Unit::AttackStop(), Unit::CombatStop(), CREATURE_ELITE_WORLDBOSS, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_MAX_SPELL, effectHandleMode, SpellInfo::Effects, Creature::GetCreatureTemplate(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::getHostileRefMgr(), WorldObject::GetInstanceScript(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::InterruptSpell(), Creature::IsDungeonBoss(), InstanceScript::IsEncounterInProgress(), Unit::IsPet(), Object::IsPlayer(), Creature::isWorldBoss(), Unit::m_lastSanctuaryTime, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::RemoveAllAttackers(), Player::SendAttackSwingCancelAttack(), SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_CASTING, unitTarget, HostileRefMgr::UpdateVisibility(), and Cell::VisitAllObjects().

◆ EffectSchoolDMG()

void Spell::EffectSchoolDMG ( SpellEffIndex  effIndex)
Todo:
: should this be put on taken but not done?
328{
330 return;
331
332 if (unitTarget && unitTarget->IsAlive())
333 {
334 bool apply_direct_bonus = true;
336 {
338 {
339 // Meteor like spells (divided damage to targets)
341 {
342 uint32 count = 0;
343 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
344 if (ihit->effectMask & (1 << effIndex))
345 ++count;
346
347 damage /= count; // divide to all targets
348 }
349 break;
350 }
352 {
353 // Shield Slam
354 if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->GetCategory() == 1209)
355 {
356 uint8 level = m_caster->GetLevel();
357 // xinef: shield block should increase the limit
358 float limit = m_caster->HasAura(2565) ? 2.0f : 1.0f;
359 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f * limit), uint32(float(level) * 34.5f * limit));
360
361 damage += int32(m_caster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value)));
362 }
363 // Victory Rush
364 else if (m_spellInfo->SpellFamilyFlags[1] & 0x100)
366 // Shockwave
367 else if (m_spellInfo->Id == 46968)
368 {
370 if (pct > 0)
372 break;
373 }
374 break;
375 }
377 {
378 // Incinerate Rank 1 & 2
379 if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128)
380 {
381 // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
382 // Check aura state for speed but aura state set not only for Immolate spell
384 {
386 damage += damage / 4;
387 }
388 }
389 // Conflagrate - consumes Immolate or Shadowflame
391 {
392 AuraEffect const* aura = nullptr; // found req. aura for damage calculation
393
395 for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
396 {
397 // for caster applied auras only
398 if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK ||
399 (*i)->GetCasterGUID() != m_caster->GetGUID())
400 continue;
401
402 // Immolate
403 if ((*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x4)
404 {
405 aura = *i; // it selected always if exist
406 break;
407 }
408
409 // Shadowflame
410 if ((*i)->GetSpellInfo()->SpellFamilyFlags[2] & 0x00000002)
411 aura = *i; // remember but wait possible Immolate as primary priority
412 }
413
414 // found Immolate or Shadowflame
415 if (aura)
416 {
417 uint32 pdamage = uint32(std::max(aura->GetAmount(), 0));
418 pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
419 uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1));
420 uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude);
421
422 damage += int32(CalculatePct(pdamage * baseTotalTicks, pct_dir));
423
424 uint32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 2)) / 3;
425 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(int32(CalculatePct(pdamage * baseTotalTicks, pct_dot)));
426
427 apply_direct_bonus = false;
428 // Glyph of Conflagrate
429 if (!m_caster->HasAura(56235))
431
432 break;
433 }
434 }
435 // Shadow Bite
436 else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000)
437 {
438 if (m_caster->IsCreature() && m_caster->IsPet())
439 {
440 if (Player* owner = m_caster->GetOwner()->ToPlayer())
441 {
442 if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
443 {
444 int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
445 m_caster->CastCustomSpell(m_caster, 54425, &bp0, nullptr, nullptr, true);
446 }
447 }
448 }
449 }
450 break;
451 }
453 {
454 // Improved Mind Blast (Mind Blast in shadow form bonus)
455 if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
456 {
458 for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
459 {
460 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
461 ((*i)->GetSpellInfo()->SpellIconID == 95))
462 {
463 int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
464 if (roll_chance_i(chance))
465 // Mind Trauma
466 m_caster->CastSpell(unitTarget, 48301, true, 0);
467 break;
468 }
469 }
470 }
471 break;
472 }
474 {
475 // Ferocious Bite
476 if (m_caster->IsPlayer() && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
477 {
478 // converts each extra point of energy into ($f1+$AP/410) additional damage
480 float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
481 int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
482 damage += int32(energy * multiple);
484 }
485 // Wrath
486 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
487 {
488 // Improved Insect Swarm
489 if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
491 AddPct(damage, aurEff->GetAmount());
492 }
493 break;
494 }
496 {
497 // Envenom
498 if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
499 {
500 if (Player* player = m_caster->ToPlayer())
501 {
502 // consume from stack dozes not more that have combo-points
503 if (uint32 combo = player->GetComboPoints())
504 {
505 // Lookup for Deadly poison (only attacker applied)
507 {
508 // count consumed deadly poison doses at target
509 bool needConsume = true;
510 uint32 spellId = aurEff->GetId();
511
512 uint32 doses = aurEff->GetBase()->GetStackAmount();
513 if (doses > combo)
514 doses = combo;
515
516 // Master Poisoner
517 Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
518 for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
519 {
520 if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
521 {
522 uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
523
524 if (chance && roll_chance_i(chance))
525 needConsume = false;
526
527 break;
528 }
529 }
530
531 if (needConsume)
532 for (uint32 i = 0; i < doses; ++i)
534
535 damage *= doses;
536 damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
537 }
538
539 // Eviscerate and Envenom Bonus Damage (item set effect)
540 if (m_caster->HasAura(37169))
541 damage += combo * 40;
542 }
543 }
544 }
545 // Eviscerate
546 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
547 {
548 if (m_caster->IsPlayer())
549 {
550 if (uint32 combo = m_caster->ToPlayer()->GetComboPoints())
551 {
553 damage += int32(ap * combo * 0.07f);
554
555 // Eviscerate and Envenom Bonus Damage (item set effect)
556 if (m_caster->HasAura(37169))
557 damage += combo * 40;
558 }
559 }
560 }
561 break;
562 }
564 {
565 //Gore
566 if (m_spellInfo->SpellIconID == 1578)
567 {
568 if (m_caster->HasAura(57627)) // Charge 6 sec post-affect
569 damage *= 2;
570 }
571 // Steady Shot
572 else if (m_spellInfo->SpellFamilyFlags[1] & 0x1)
573 {
574 bool found = false;
575 // check dazed affect
577 for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
578 {
579 if ((*iter)->GetSpellInfo()->SpellIconID == 15 && (*iter)->GetSpellInfo()->Dispel == 0)
580 {
581 found = true;
582 break;
583 }
584 }
585
587 if (found)
588 damage += m_spellInfo->Effects[EFFECT_1].CalcValue();
589
590 if (Player* caster = m_caster->ToPlayer())
591 {
592 // Add Ammo and Weapon damage plus RAP * 0.1
593 float dmg_min = 0.f;
594 float dmg_max = 0.f;
595 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
596 {
597 dmg_min += caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE, i);
598 dmg_max += caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE, i);
599 }
600
601 if (dmg_max == 0.0f && dmg_min > dmg_max)
602 {
603 damage += int32(dmg_min);
604 }
605 else
606 {
607 damage += irand(int32(dmg_min), int32(dmg_max));
608 }
609 damage += int32(caster->GetAmmoDPS() * caster->GetAttackTime(RANGED_ATTACK) * 0.001f);
610 }
611 }
612 break;
613 }
615 {
616 // Hammer of the Righteous
617 if (m_spellInfo->SpellFamilyFlags[1] & 0x00040000)
618 {
619 // Add main hand dps * effect[2] amount
620 if (Player* player = m_caster->ToPlayer())
621 {
622 float minTotal = 0.f;
623 float maxTotal = 0.f;
624 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
625 {
626 float tmpMin, tmpMax;
627 player->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i);
628 minTotal += tmpMin;
629 maxTotal += tmpMax;
630 }
631
632 float average = (minTotal + maxTotal) / 2;
635 }
636 break;
637 }
638 // Shield of Righteousness
639 if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000)
640 {
641 uint8 level = m_caster->GetLevel();
642 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 34.5f));
643 if (m_caster->GetAuraEffect(64882, EFFECT_0))
644 block_value += 225;
645 damage += CalculatePct(block_value, m_spellInfo->Effects[EFFECT_1].CalcValue());
646 break;
647 }
648 break;
649 }
650 }
651
652 if (m_originalCaster /*&& damage > 0 Xinef: this can be increased from 0*/ && apply_direct_bonus)
653 {
654 // Xinef: protection
655 if (damage < 0)
656 damage = 0;
657
660 }
661
662 m_damage += damage;
663 }
664}
@ MINDAMAGE
Definition: Unit.h:135
@ MAXDAMAGE
Definition: Unit.h:136
@ FORM_SHADOW
Definition: UnitDefines.h:95
#define MAX_ITEM_PROTO_DAMAGES
Definition: ItemTemplate.h:613
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK
Definition: SpellAuraDefines.h:309
@ SPELL_AURA_PERIODIC_DAMAGE
Definition: SpellAuraDefines.h:66
@ SPELL_AURA_ADD_FLAT_MODIFIER
Definition: SpellAuraDefines.h:170
@ SPELL_AURA_MOD_DECREASE_SPEED
Definition: SpellAuraDefines.h:96
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition: SpellInfo.h:179
@ EFFECT_2
Definition: SharedDefines.h:33
@ POWER_ENERGY
Definition: SharedDefines.h:272
@ SPELLFAMILY_PRIEST
Definition: SharedDefines.h:3534
@ AURA_STATE_CONFLAGRATE
Definition: SharedDefines.h:1306
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit *pVictim=nullptr) const
Definition: Unit.cpp:15382
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition: Unit.cpp:14783
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4906
uint32 GetAttackTime(WeaponAttackType att) const
Definition: Unit.h:800
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition: Unit.h:1383
uint8 GetStackAmount() const
Definition: SpellAuras.h:148

References AddPct(), Unit::ApplyEffectModifiers(), ApplyPct(), AURA_STATE_CONFLAGRATE, BASE_ATTACK, Unit::CalcSpellDuration(), CalculatePct(), Unit::CalculateSpellDamage(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, DOT, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, FORM_SHADOW, AuraEffect::GetAmount(), Unit::GetAttackTime(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), SpellInfo::GetCategory(), Unit::GetComboPoints(), Unit::GetDummyAuraEffect(), Object::GetGUID(), AuraEffect::GetId(), Unit::GetLevel(), Unit::GetOwner(), Unit::GetShapeshiftForm(), Unit::GetShieldBlockValue(), AuraEffect::GetSpellInfo(), Aura::GetStackAmount(), Unit::GetTotalAttackPowerValue(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), SpellInfo::Id, IN_MILLISECONDS, irand(), Unit::IsAlive(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_damage, m_originalCaster, m_spellInfo, m_spellValue, m_UniqueTargetInfo, MAX_ITEM_PROTO_DAMAGES, MAXDAMAGE, MINDAMAGE, Unit::ModifyPower(), POWER_ENERGY, RANGED_ATTACK, Unit::RemoveAuraFromStack(), Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_PERIODIC_DAMAGE, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_PRIEST, SPELLFAMILY_ROGUE, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SpellInfo::SpellVisual, SpellInfo::TargetAuraState, Object::ToPlayer(), and unitTarget.

◆ EffectScriptEffect()

void Spell::EffectScriptEffect ( SpellEffIndex  effIndex)
Todo:
: we must implement hunter pet summon at login there (spell 6962)
3767{
3769 return;
3770
3772
3774 {
3776 {
3777 switch (m_spellInfo->Id)
3778 {
3779 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3780 case 22539:
3781 case 22972:
3782 case 22975:
3783 case 22976:
3784 case 22977:
3785 case 22978:
3786 case 22979:
3787 case 22980:
3788 case 22981:
3789 case 22982:
3790 case 22983:
3791 case 22984:
3792 case 22985:
3793 {
3794 if (!unitTarget || !unitTarget->IsAlive())
3795 return;
3796
3797 // Onyxia Scale Cloak
3798 if (unitTarget->HasAura(22683))
3799 return;
3800
3801 // Shadow Flame
3802 m_caster->CastSpell(unitTarget, 22682, true);
3803 return;
3804 }
3805 // Plant Warmaul Ogre Banner
3806 case 32307:
3807 if (Player* caster = m_caster->ToPlayer())
3808 {
3809 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
3810 if (Creature* target = unitTarget->ToCreature())
3811 {
3812 target->setDeathState(DeathState::Corpse);
3813 target->RemoveCorpse();
3814 }
3815 }
3816 break;
3817 // SOTA defender teleport
3818 case 54640:
3819 {
3820 if (Player* player = unitTarget->ToPlayer())
3821 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
3822 {
3823 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
3824 {
3825 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
3826 bg->DefendersPortalTeleport(dportal, player);
3827 }
3828 }
3829 return;
3830 }
3831 /*// Mug Transformation
3832 case 41931:
3833 {
3834 if (!m_caster->IsPlayer())
3835 return;
3836
3837 uint8 bag = 19;
3838 uint8 slot = 0;
3839 Item* item = nullptr;
3840
3841 while (bag) // 256 = 0 due to var type
3842 {
3843 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3844 if (item && item->GetEntry() == 38587)
3845 break;
3846
3847 ++slot;
3848 if (slot == 39)
3849 {
3850 slot = 0;
3851 ++bag;
3852 }
3853 }
3854 if (bag)
3855 {
3856 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3857 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3858 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3859 m_caster->CastSpell(m_caster, 42518, true);
3860 return;
3861 }
3862 break;
3863 }*/
3864 // Roll Dice - Decahedral Dwarven Dice
3865 case 47770:
3866 {
3867 char buf[128];
3868 const char* gender = "his";
3869 if (m_caster->getGender() > 0)
3870 gender = "her";
3871 snprintf(buf, sizeof(buf), "%s rubs %s [Decahedral Dwarven Dice] between %s hands and rolls. One %u and one %u.", m_caster->GetName().c_str(), gender, gender, urand(1, 10), urand(1, 10));
3872 m_caster->TextEmote(buf);
3873 break;
3874 }
3875 case 52173: // Coyote Spirit Despawn
3876 case 60243: // Blood Parrot Despawn
3879 return;
3880 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3881 {
3883 return;
3884
3886
3887 return;
3888 }
3889 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3890 {
3891 if (!m_caster->IsPlayer())
3892 return;
3893
3894 // Delete item from inventory at death
3896
3897 return;
3898 }
3899 case 58418: // Portal to Orgrimmar
3900 case 58420: // Portal to Stormwind
3901 {
3902 if (!unitTarget || !unitTarget->IsPlayer() || effIndex != 0)
3903 return;
3904
3905 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
3906 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
3907
3909 unitTarget->CastSpell(unitTarget, spellID, true);
3910
3911 return;
3912 }
3913 // Stoneclaw Totem
3914 case 55328: // Rank 1
3915 case 55329: // Rank 2
3916 case 55330: // Rank 3
3917 case 55332: // Rank 4
3918 case 55333: // Rank 5
3919 case 55335: // Rank 6
3920 case 55278: // Rank 7
3921 case 58589: // Rank 8
3922 case 58590: // Rank 9
3923 case 58591: // Rank 10
3924 {
3925 int32 basepoints0 = damage;
3926 // Cast Absorb on totems
3927 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
3928 {
3929 if (!unitTarget->m_SummonSlot[slot])
3930 continue;
3931
3933 if (totem && totem->IsTotem())
3934 {
3935 m_caster->CastCustomSpell(totem, 55277, &basepoints0, nullptr, nullptr, true);
3936 }
3937 }
3938 // Glyph of Stoneclaw Totem
3939 if (AuraEffect* aur = unitTarget->GetAuraEffect(63298, 0))
3940 {
3941 basepoints0 *= aur->GetAmount();
3942 m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, nullptr, nullptr, true);
3943 }
3944 break;
3945 }
3946 case 61263: // for item Intravenous Healing Potion (44698)
3947 {
3948 if (!m_caster || !unitTarget)
3949 return;
3950
3951 m_caster->CastSpell(m_caster, 61267, true);
3952 m_caster->CastSpell(m_caster, 61268, true);
3953 return;
3954 }
3955 }
3956 break;
3957 }
3958 case SPELLFAMILY_ROGUE:
3959 {
3960 switch (m_spellInfo->Id)
3961 {
3962 // Master of Subtlety
3963 case 31666:
3964 {
3965 if (!unitTarget)
3966 return;
3967
3968 Aura* mos = unitTarget->GetAura(31665);
3969 if (mos)
3970 {
3971 mos->SetMaxDuration(6000);
3972 mos->SetDuration(6000, true);
3973 }
3974
3975 break;
3976 }
3977 // Overkill
3978 case 58428:
3979 {
3980 if (!unitTarget)
3981 return;
3982
3983 Aura* overkill = unitTarget->GetAura(58427);
3984 if (overkill)
3985 {
3986 overkill->SetMaxDuration(20000);
3987 overkill->SetDuration(20000, true);
3988 }
3989
3990 break;
3991 }
3992 }
3993 break;
3994 }
3995 }
3996
3997 // normal DB scripted effect
3998 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
4000}
@ QUEST_STATUS_COMPLETE
Definition: QuestDef.h:101
@ BATTLEGROUND_SA
Definition: SharedDefines.h:3489
Class for manage Strand of Ancient battleground.
Definition: BattlegroundSA.h:456
void DefendersPortalTeleport(GameObject *portal, Player *plr)
Definition: BattlegroundSA.cpp:585
void DespawnOrUnsummon(Milliseconds msTimeToDespawn, Seconds forcedRespawnTimer)
Definition: Creature.cpp:2177
virtual void UnSummon(uint32 msTime=0)
Definition: TemporarySummon.cpp:282
GameObject * FindNearestGameObject(uint32 entry, float range, bool onlySpawned=false) const
Definition: Object.cpp:2455
std::string const & GetName() const
Definition: Object.h:458
uint8 getGender() const
Definition: Unit.h:752
bool IsSummon() const
Definition: Unit.h:707
virtual void TextEmote(std::string_view text, WorldObject const *target=nullptr, bool isBossEmote=false)
Definition: Unit.cpp:21114

References BATTLEGROUND_SA, Unit::CastCustomSpell(), Unit::CastSpell(), damage, BattlegroundSA::DefendersPortalTeleport(), Creature::DespawnOrUnsummon(), Player::DestroyItemCount(), EFFECT_0, EFFECT_1, effectHandleMode, SpellInfo::Effects, WorldObject::FindNearestGameObject(), Unit::GetAura(), Unit::GetAuraEffect(), Map::GetCreature(), Unit::getGender(), WorldObject::GetMap(), WorldObject::GetName(), Player::GetQuestStatus(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsCreature(), Object::IsPlayer(), Unit::IsSummon(), Unit::IsTotem(), LOG_DEBUG, m_caster, m_spellInfo, Unit::m_SummonSlot, MAX_TOTEM_SLOT, QUEST_STATUS_COMPLETE, Map::ScriptsStart(), Aura::SetDuration(), Aura::SetMaxDuration(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sSpellScripts, SUMMON_SLOT_TOTEM, Unit::TextEmote(), Object::ToCreature(), Object::ToPlayer(), Unit::ToTempSummon(), unitTarget, TempSummon::UnSummon(), and urand().

◆ EffectSelfResurrect()

void Spell::EffectSelfResurrect ( SpellEffIndex  effIndex)
4829{
4831 return;
4832
4833 if (!m_caster || m_caster->IsAlive())
4834 return;
4835 if (!m_caster->IsPlayer())
4836 return;
4837 if (!m_caster->IsInWorld())
4838 return;
4839
4840 uint32 health = 0;
4841 uint32 mana = 0;
4842
4843 // flat case
4844 if (damage < 0)
4845 {
4846 health = uint32(-damage);
4847 mana = m_spellInfo->Effects[effIndex].MiscValue;
4848 }
4849 // percent case
4850 else
4851 {
4855 }
4856
4857 Player* player = m_caster->ToPlayer();
4858 player->ResurrectPlayer(0.0f);
4859
4860 player->SetHealth(health);
4861 player->SetPower(POWER_MANA, mana);
4862 player->SetPower(POWER_RAGE, 0);
4863 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4864
4865 player->SpawnCorpseBones();
4866}
@ POWER_RAGE
Definition: SharedDefines.h:270
void SpawnCorpseBones(bool triggerSave=true)
Definition: Player.cpp:4672
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition: Player.cpp:4459
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition: Unit.cpp:15520

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, SpellInfo::Effects, Unit::GetMaxPower(), Unit::IsAlive(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_ENERGY, POWER_MANA, POWER_RAGE, Player::ResurrectPlayer(), Unit::SetHealth(), Unit::SetPower(), Player::SpawnCorpseBones(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectSendEvent()

void Spell::EffectSendEvent ( SpellEffIndex  effIndex)
Todo:
: there should be a possibility to pass dest target to event script
1378{
1379 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1382 return;
1383
1384 WorldObject* target = nullptr;
1385
1386 // call events for object target if present
1388 {
1389 if (unitTarget)
1390 target = unitTarget;
1391 else if (gameObjTarget)
1392 target = gameObjTarget;
1393 }
1394 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1395 {
1396 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1397 // this check was requested by scripters, but it has some downsides:
1398 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1399 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1400 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1401 return;
1402 // some spells have no target entries in dbc and they use focus target
1403 if (focusObject)
1404 target = focusObject;
1406 }
1407
1408 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1409
1410 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1411 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1412 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1413 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1414
1415 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1416}
ScriptMapMap sEventScripts
Definition: ObjectMgr.cpp:58
@ TARGET_FLAG_UNIT_MASK
Definition: SpellInfo.h:68
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition: SpellInfo.h:70
Definition: Object.h:405
ZoneScript * GetZoneScript() const
Definition: Object.h:537
Definition: ZoneScript.h:27

References effectHandleMode, SpellInfo::Effects, focusObject, gameObjTarget, WorldObject::GetInstanceScript(), WorldObject::GetMap(), WorldObject::GetZoneScript(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), sEventScripts, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_UNIT_MASK, and unitTarget.

◆ EffectSendTaxi()

void Spell::EffectSendTaxi ( SpellEffIndex  effIndex)
5088{
5090 return;
5091
5092 if (!unitTarget)
5093 return;
5094
5095 if (Player* player = unitTarget->ToPlayer())
5096 {
5097 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5098 }
5099}

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5521{
5523 return;
5524
5525 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5526}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4869{
4871 return;
4872
4873 if (!unitTarget->IsCreature())
4874 return;
4875 if (!m_caster->IsPlayer())
4876 return;
4877
4878 Creature* creature = unitTarget->ToCreature();
4879 int32 targetLevel = creature->GetLevel();
4880
4881 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4882
4886
4887 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4888
4889 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4890
4891 // Double chances for elites
4892 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4893}
@ UNIT_DYNFLAG_LOOTABLE
Definition: SharedDefines.h:3121
bool isElite() const
Definition: Creature.h:114
virtual void SetDynamicFlag(uint32 flag)
Definition: Object.h:120

References effectHandleMode, Creature::GetCreatureTemplate(), Object::GetGUID(), Unit::GetLevel(), Player::GetPureSkillValue(), CreatureTemplate::GetRequiredLootSkill(), Object::IsCreature(), Creature::isElite(), Object::IsPlayer(), LOOT_SKINNING, m_caster, Unit::RemoveUnitFlag(), Player::SendLoot(), Object::SetDynamicFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_DYNFLAG_LOOTABLE, UNIT_FLAG_SKINNABLE, unitTarget, and Player::UpdateGatherSkill().

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5552{
5554 return;
5555
5556 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5557 if ((!m_caster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5558 return;
5559
5561}
void RemovedInsignia(Player *looterPlr)
Definition: Player.cpp:7734

References effectHandleMode, Unit::IsAlive(), Object::IsPlayer(), LOG_DEBUG, m_caster, Player::RemovedInsignia(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6107{
6109 return;
6110
6111 if (!unitTarget)
6112 return;
6113
6114 if (Player* player = unitTarget->ToPlayer())
6115 {
6116 player->UpdateSpecCount(damage);
6117 }
6118}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5533{
5535 return;
5536
5537 /*
5538 if (!unitTarget->IsPlayer())
5539 return;
5540 if (!unitTarget->IsInWorld())
5541 return;
5542
5543 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5544 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5545 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5546 unitTarget->ToPlayer()->SpawnCorpseBones();
5547 */
5548}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5564{
5566 return;
5567
5568 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5569
5570 if (!unitTarget || unitTarget == m_caster) // can't steal from self
5571 return;
5572
5573 DispelChargesList steal_list;
5574
5575 // Create dispel mask by dispel type
5576 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5577 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5578 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5579 {
5580 Aura* aura = itr->second;
5582 if (!aurApp)
5583 continue;
5584
5585 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5586 {
5587 // Need check for passive? this
5588 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5589 continue;
5590
5591 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5592 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5593 // Polymorph instead of 1 / (5 + 1) -> 16%.
5594 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5595 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5596 if (charges > 0)
5597 steal_list.push_back(std::make_pair(aura, charges));
5598 }
5599 }
5600
5601 if (steal_list.empty())
5602 return;
5603
5604 // Ok if exist some buffs for dispel try dispel it
5605 uint32 failCount = 0;
5606 DispelList success_list;
5607 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5608 // dispel N = damage buffs (or while exist buffs for dispel)
5609 for (int32 count = 0; count < damage && !steal_list.empty();)
5610 {
5611 // Random select buff for dispel
5612 DispelChargesList::iterator itr = steal_list.begin();
5613 std::advance(itr, urand(0, steal_list.size() - 1));
5614
5615 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
5616 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5617 if (!chance)
5618 {
5619 steal_list.erase(itr);
5620 continue;
5621 }
5622 else
5623 {
5624 if (roll_chance_i(chance))
5625 {
5626 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5627 --itr->second;
5628 if (itr->second <= 0)
5629 steal_list.erase(itr);
5630 }
5631 else
5632 {
5633 if (!failCount)
5634 {
5635 // Failed to dispell
5636 dataFail << m_caster->GetGUID(); // Caster GUID
5637 dataFail << unitTarget->GetGUID(); // Victim GUID
5638 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5639 }
5640 ++failCount;
5641 dataFail << uint32(itr->first->GetId()); // Spell Id
5642 }
5643 ++count;
5644 }
5645 }
5646
5647 if (failCount)
5648 m_caster->SendMessageToSet(&dataFail, true);
5649
5650 if (success_list.empty())
5651 return;
5652
5653 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5654 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5655 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
5656 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5657 dataSuccess << uint8(0); // not used
5658 dataSuccess << uint32(success_list.size()); // count
5659 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5660 {
5661 dataSuccess << uint32(itr->first); // Spell Id
5662 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5663 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5664 }
5665 m_caster->SendMessageToSet(&dataSuccess, true);
5666}
std::list< std::pair< uint32, ObjectGuid > > DispelList
Definition: SpellEffects.cpp:2543
@ SPELL_ATTR7_DISPEL_REMOVES_CHARGES
Definition: SharedDefines.h:651
@ SPELL_ATTR4_CANNOT_BE_STOLEN
Definition: SharedDefines.h:536
@ SMSG_SPELLSTEALLOG
Definition: Opcodes.h:849
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
Definition: Unit.cpp:4987
bool IsPositive() const
Definition: SpellAuras.h:68
uint8 GetCharges() const
Definition: SpellAuras.h:141
bool IsPassive() const
Definition: SpellAuras.cpp:1082

References damage, effectHandleMode, SpellInfo::Effects, Aura::GetApplicationOfTarget(), Aura::GetCharges(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::GetOwnedAuras(), Object::GetPackGUID(), Aura::GetSpellInfo(), Aura::GetStackAmount(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsFriendlyTo(), Aura::IsPassive(), AuraApplication::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellBySteal(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLSTEALLOG, SPELL_ATTR4_CANNOT_BE_STOLEN, SPELL_ATTR7_DISPEL_REMOVES_CHARGES, SPELL_EFFECT_HANDLE_HIT_TARGET, unitTarget, and urand().

◆ EffectStuck()

void Spell::EffectStuck ( SpellEffIndex  effIndex)
4160{
4162 return;
4163
4164 if (!m_caster->IsPlayer())
4165 return;
4166
4167 Player* target = m_caster->ToPlayer();
4168 if (target->IsInFlight())
4169 return;
4170
4171 // xinef: if player is dead - teleport to graveyard
4172 if (!target->IsAlive())
4173 {
4175 return;
4176
4177 // xinef: player is in corpse
4178 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4179 target->BuildPlayerRepop();
4180 target->RepopAtGraveyard();
4181 return;
4182 }
4183
4184 // xinef: no hearthstone in bag or on cooldown
4185 Item* hearthStone = target->GetItemByEntry(6948);
4186 if (!hearthStone || target->HasSpellCooldown(8690))
4187 {
4188 float o = rand_norm() * 2 * M_PI;
4189 Position pos = *target;
4190 target->MovePositionToFirstCollision(pos, 5.0f, o);
4191 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4192 return;
4193 }
4194
4195 // xinef: we have hearthstone not on cooldown, just use it
4197}
double rand_norm()
Definition: Random.cpp:77
@ PLAYER_FLAGS_GHOST
Definition: Player.h:478
@ SPELL_AURA_PREVENT_RESURRECTION
Definition: SpellAuraDefines.h:377
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition: Object.cpp:2860
void RepopAtGraveyard()
Definition: Player.cpp:4906
void BuildPlayerRepop()
Definition: Player.cpp:4410

References Player::BuildPlayerRepop(), Unit::CastSpell(), effectHandleMode, Player::GetItemByEntry(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::HasAuraType(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::IsAlive(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, WorldObject::MovePositionToFirstCollision(), Unit::NearTeleportTo(), PLAYER_FLAGS_GHOST, rand_norm(), Player::RepopAtGraveyard(), SPELL_AURA_PREVENT_RESURRECTION, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), TRIGGERED_FULL_MASK, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2181{
2183 return;
2184
2185 if (!m_caster->IsPlayer())
2186 return;
2187
2188 Player* player = m_caster->ToPlayer();
2189
2190 // applied only to using item
2191 if (!m_CastItem)
2192 return;
2193
2194 // ... only to item in own inventory/bank/equip_slot
2195 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2196 return;
2197
2198 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2199 if (!newitemid)
2200 return;
2201
2202 uint16 pos = m_CastItem->GetPos();
2203
2204 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2205 if (!pNewItem)
2206 return;
2207
2208 // Client-side enchantment durations update
2210
2214
2216 {
2218 player->DurabilityLoss(pNewItem, lossPercent);
2219 }
2220
2221 if (player->IsInventoryPos(pos))
2222 {
2223 ItemPosCountVec dest;
2224 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2225 if (msg == EQUIP_ERR_OK)
2226 {
2227 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2228
2229 // prevent crash at access and unexpected charges counting with item update queue corrupt
2231 m_targets.SetItemTarget(nullptr);
2232
2233 m_CastItem = nullptr;
2235
2236 player->StoreItem(dest, pNewItem, true);
2237 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2238 return;
2239 }
2240 }
2241 else if (player->IsBankPos(pos))
2242 {
2243 ItemPosCountVec dest;
2244 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2245 if (msg == EQUIP_ERR_OK)
2246 {
2247 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2248
2249 // prevent crash at access and unexpected charges counting with item update queue corrupt
2251 m_targets.SetItemTarget(nullptr);
2252
2253 m_CastItem = nullptr;
2255
2256 player->BankItem(dest, pNewItem, true);
2257 return;
2258 }
2259 }
2260 else if (player->IsEquipmentPos(pos))
2261 {
2262 uint16 dest;
2263
2264 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2265
2266 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2267
2268 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2269 {
2271
2272 // prevent crash at access and unexpected charges counting with item update queue corrupt
2274 m_targets.SetItemTarget(nullptr);
2275
2276 m_CastItem = nullptr;
2278
2279 player->EquipItem(dest, pNewItem, true);
2280 player->AutoUnequipOffhandIfNeed();
2281 return;
2282 }
2283 }
2284
2285 // fail
2286 delete pNewItem;
2287}
@ ITEM_FIELD_DURABILITY
Definition: UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition: UpdateFields.h:70
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition: Item.h:86
uint8 GetSlot() const
Definition: Item.h:281
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition: Item.cpp:1088
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:305
uint16 GetPos() const
Definition: Item.h:285
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:306
uint8 GetBagSlot() const
Definition: Item.cpp:785
void Clear()
Definition: ObjectGuid.h:138
static bool IsEquipmentPos(uint16 pos)
Definition: Player.h:1258
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:1807
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition: Player.h:1327
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition: Player.h:1278
void UpdateEnchantmentDurations()
Definition: PlayerStorage.cpp:4736
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2576
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: PlayerStorage.cpp:3025
static bool IsInventoryPos(uint16 pos)
Definition: Player.h:1256
void AutoUnequipOffhandIfNeed(bool force=false)
Definition: Player.cpp:12462
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2729
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:2034
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition: PlayerQuest.cpp:1829
static bool IsBankPos(uint16 pos)
Definition: Player.h:1261

References Player::AutoUnequipOffhandIfNeed(), Player::BankItem(), Player::CanBankItem(), Player::CanEquipItem(), Player::CanStoreItem(), ObjectGuid::Clear(), Item::CreateItem(), Player::DestroyItem(), Player::DurabilityLoss(), effectHandleMode, SpellInfo::Effects, EQUIP_ERR_CANT_DO_RIGHT_NOW, EQUIP_ERR_OK, Player::EquipItem(), EQUIPMENT_SLOT_MAINHAND, Item::GetBagSlot(), Item::GetEnchantmentCharges(), Item::GetEnchantmentDuration(), Item::GetEnchantmentId(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetOwnerGUID(), Item::GetPos(), Item::GetSlot(), Object::GetUInt32Value(), Player::IsBankPos(), Player::IsEquipmentPos(), Player::IsInventoryPos(), Object::IsPlayer(), ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, Player::ItemAddedQuestCheck(), m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT, Player::StoreItem(), TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and Player::UpdateEnchantmentDurations().

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

void Spell::EffectSummonObject ( SpellEffIndex  effIndex)
4547{
4549 return;
4550
4551 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4552
4553 uint8 slot = 0;
4554 switch (m_spellInfo->Effects[effIndex].Effect)
4555 {
4557 slot = 0;
4558 break;
4560 slot = 1;
4561 break;
4563 slot = 2;
4564 break;
4566 slot = 3;
4567 break;
4568 default:
4569 return;
4570 }
4571
4572 if (m_caster)
4573 {
4574 ObjectGuid guid = m_caster->m_ObjectSlot[slot];
4575 if (guid)
4576 {
4577 if (GameObject* gameObject = m_caster->GetMap()->GetGameObject(guid))
4578 {
4579 // Recast case - null spell id to make auras not be removed on object remove from world
4580 if (m_spellInfo->Id == gameObject->GetSpellId())
4581 gameObject->SetSpellId(0);
4582 m_caster->RemoveGameObject(gameObject, true);
4583 }
4584 m_caster->m_ObjectSlot[slot].Clear();
4585 }
4586 }
4587
4588 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4589
4590 float x, y, z;
4591 // If dest location if present
4592 if (m_targets.HasDst())
4593 destTarget->GetPosition(x, y, z);
4594 // Summon in random point all other units if location present
4595 else
4597
4598 Map* map = m_caster->GetMap();
4599 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4600 {
4601 delete pGameObj;
4602 return;
4603 }
4604
4605 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
4606 int32 duration = m_spellInfo->GetDuration();
4607 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4608 pGameObj->SetSpellId(m_spellInfo->Id);
4609 m_caster->AddGameObject(pGameObj);
4610
4611 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4612
4613 map->AddToMap(pGameObj, true);
4614
4615 m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4616}
#define DEFAULT_WORLD_OBJECT_SIZE
Definition: ObjectDefines.h:45
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT4
Definition: SharedDefines.h:885
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT1
Definition: SharedDefines.h:882
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT3
Definition: SharedDefines.h:884
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT2
Definition: SharedDefines.h:883
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition: Unit.h:1798

References Unit::AddGameObject(), Map::AddToMap(), ObjectGuid::Clear(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Map::GetGameObject(), Object::GetGUID(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, Unit::m_ObjectSlot, m_spellInfo, m_targets, Unit::RemoveGameObject(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_SUMMON_OBJECT_SLOT1, SPELL_EFFECT_SUMMON_OBJECT_SLOT2, SPELL_EFFECT_SUMMON_OBJECT_SLOT3, and SPELL_EFFECT_SUMMON_OBJECT_SLOT4.

◆ EffectSummonObjectWild()

void Spell::EffectSummonObjectWild ( SpellEffIndex  effIndex)
3717{
3719 return;
3720
3721 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3722
3723 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3724
3725 WorldObject* target = focusObject;
3726 if (!target)
3727 target = m_caster;
3728
3729 float x, y, z;
3730 if (m_targets.HasDst())
3731 destTarget->GetPosition(x, y, z);
3732 else
3734
3735 Map* map = target->GetMap();
3736
3737 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
3738 {
3739 delete pGameObj;
3740 return;
3741 }
3742
3743 int32 duration = m_spellInfo->GetDuration();
3744
3745 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3746 pGameObj->SetSpellId(m_spellInfo->Id);
3747
3748 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3749
3750 // Wild object not have owner and check clickable by players
3751 map->AddToMap(pGameObj, true);
3752
3753 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3754 if (Player* player = m_caster->ToPlayer())
3755 if (Battleground* bg = player->GetBattleground())
3756 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3757
3758 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3759 {
3760 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3761 linkedTrap->SetSpellId(m_spellInfo->Id);
3762 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3763 }
3764}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition: SharedDefines.h:1586
@ TEAM_ALLIANCE
Definition: SharedDefines.h:760
@ TEAM_HORDE
Definition: SharedDefines.h:761
GameObject * GetLinkedTrap()
Definition: GameObject.cpp:2735
GameobjectTypes GetGoType() const
Definition: GameObject.h:204

References Map::AddToMap(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), focusObject, GAMEOBJECT_TYPE_FLAGDROP, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), GameObject::GetGoType(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, m_spellInfo, m_targets, GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, TEAM_ALLIANCE, TEAM_HORDE, and Object::ToPlayer().

◆ EffectSummonPet()

void Spell::EffectSummonPet ( SpellEffIndex  effIndex)
3119{
3121 return;
3122
3123 if (!m_originalCaster)
3124 return;
3125
3126 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3127 int32 duration = m_spellInfo->GetDuration();
3128
3129 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
3130 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3131
3132 Player* owner = m_originalCaster->ToPlayer();
3133 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3135
3136 if (!owner)
3137 {
3138 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3139 if (properties)
3140 {
3141 // Xinef: unsummon old guardian
3142 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3143 oldPet->UnSummon();
3144 SummonGuardian(effIndex, petentry, properties, 1, false);
3145 }
3146 return;
3147 }
3148
3149 Pet* OldSummon = owner->GetPet();
3150
3151 // if pet requested type already exist
3152 if (OldSummon)
3153 {
3154 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3155 {
3156 // pet in corpse state can't be summoned
3157 if (OldSummon->isDead())
3158 return;
3159
3160 ASSERT(OldSummon->GetMap() == owner->GetMap());
3161
3162 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3163
3164 float px, py, pz;
3165 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3166
3167 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3168 OldSummon->UpdateObjectVisibility();
3169
3170 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3171 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3172 // notify player
3173 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3174 owner->SendClearCooldown(itr->first, OldSummon);
3175
3176 // actually clear cooldowns
3177 OldSummon->m_CreatureSpellCooldowns.clear();
3178 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3179 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3180 {
3181 Aura const* aura = i->second->GetBase();
3182 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3183 OldSummon->RemoveAura(i);
3184 else
3185 ++i;
3186 }
3187 return;
3188 }
3189
3190 if (owner->IsPlayer())
3191 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3192 else
3193 return;
3194 }
3195
3196 float x, y, z;
3197 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3198 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3199 if (!pet)
3200 return;
3201
3202 if (m_caster->IsCreature())
3203 {
3204 if (m_caster->ToCreature()->IsTotem())
3206 else
3208 }
3209
3211
3212 // Reset cooldowns
3214 {
3215 pet->m_CreatureSpellCooldowns.clear();
3216 owner->PetSpellInitialize();
3217 }
3218
3219 // Set health to max if new pet is summoned
3220 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3221 // pet should have full health
3222 pet->SetHealth(pet->GetMaxHealth());
3223
3224 // generate new name for summon pet
3225 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3226 if (!new_name.empty())
3227 pet->SetName(new_name);
3228
3229 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3230}
@ REACT_DEFENSIVE
Definition: Unit.h:549
@ REACT_AGGRESSIVE
Definition: Unit.h:550
@ SPELLMOD_DURATION
Definition: SpellDefines.h:78
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition: Creature.h:254
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition: Creature.h:97
Definition: TemporarySummon.h:95
void SetName(std::string const &newname)
Definition: Object.h:459
float GetObjectSize() const
Definition: Object.cpp:2771
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition: Player.cpp:14654
bool IsPetAura(Aura const *aura)
Definition: Unit.cpp:17291
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition: Unit.cpp:19085
Powers getPowerType() const
Definition: Unit.h:888
bool isDead() const
Definition: Unit.h:1218
bool CanBeSentToClient() const
Definition: SpellAuras.cpp:1137
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition: SpellEffects.cpp:5932

References ASSERT, Aura::CanBeSentToClient(), CLASS_CONTEXT_PET, CLASS_HUNTER, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetEntry(), Unit::GetGuardianPet(), WorldObject::GetMap(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetObjectSize(), Position::GetOrientation(), Player::GetPet(), Unit::getPowerType(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsCreature(), Unit::isDead(), Aura::IsPassive(), Unit::IsPetAura(), Object::IsPlayer(), Unit::IsTotem(), m_caster, Creature::m_CreatureSpellCooldowns, m_originalCaster, m_spellInfo, Unit::NearTeleportTo(), PET_SAVE_NOT_IN_SLOT, Player::PetSpellInitialize(), REACT_AGGRESSIVE, REACT_DEFENSIVE, Unit::RemoveAura(), Player::RemovePet(), Player::SendClearCooldown(), Unit::SetHealth(), WorldObject::SetName(), Unit::SetPower(), Creature::SetReactState(), Unit::SetUInt32Value(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, sSummonPropertiesStore, SUMMON_PET, SummonGuardian(), Player::SummonPet(), Object::ToCreature(), Object::ToPlayer(), UNIT_CREATED_BY_SPELL, and Unit::UpdateObjectVisibility().

◆ EffectSummonPlayer()

void Spell::EffectSummonPlayer ( SpellEffIndex  effIndex)
4200{
4201 // workaround - this effect should not use target map
4203 return;
4204
4205 if (!unitTarget)
4206 return;
4207
4208 Player* player = unitTarget->ToPlayer();
4209 if (!player)
4210 {
4211 return;
4212 }
4213
4214 // Evil Twin (ignore player summon, but hide this for summoner)
4215 // Xinef: Unit Target may be on other map!!!, Need workaround
4216 if (unitTarget->HasAura(23445))
4217 return;
4218
4219 float x, y, z;
4220 m_caster->GetPosition(x, y, z);
4221
4222 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4223
4224 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4225 data << m_caster->GetGUID(); // summoner guid
4226 data << uint32(m_caster->GetZoneId()); // summoner zone
4227 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4228 player->GetSession()->SendPacket(&data);
4229}
#define MAX_PLAYER_SUMMON_DELAY
Definition: Player.h:929
@ SMSG_SUMMON_REQUEST
Definition: Opcodes.h:713
void SetSummonPoint(uint32 mapid, float x, float y, float z, uint32 delay=0, bool asSpectator=false)
Definition: Player.cpp:16322

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), Unit::HasAura(), IN_MILLISECONDS, m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonRaFFriend()

void Spell::EffectSummonRaFFriend ( SpellEffIndex  effIndex)
6301{
6303 return;
6304
6305 if (!m_caster->IsPlayer())
6306 return;
6307
6308 if (!unitTarget)
6309 return;
6310
6311 Player* player = unitTarget->ToPlayer();
6312 if (!player)
6313 {
6314 return;
6315 }
6316
6317 float x, y, z;
6318 m_caster->GetPosition(x, y, z);
6320 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6321 data << m_caster->GetGUID();
6322 data << uint32(m_caster->GetZoneId());
6323 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6324 player->GetSession()->SendPacket(&data);
6325}

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), IN_MILLISECONDS, Object::IsPlayer(), m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2312{
2314 return;
2315
2316 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2317 if (!entry)
2318 return;
2319
2320 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2321 if (!properties)
2322 {
2323 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2324 return;
2325 }
2326
2327 if (!m_originalCaster)
2328 return;
2329
2330 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2331 int32 duration = m_spellInfo->GetDuration();
2332 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2333 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2334
2335 TempSummon* summon = nullptr;
2336
2337 // determine how many units should be summoned
2338 uint32 numSummons;
2339
2340 // some spells need to summon many units, for those spells number of summons is stored in effect value
2341 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2342 // and in spell attributes, possibly we need to add a table for those)
2343 // so here's a list of MiscValueB values, which is currently most generic check
2344 switch (properties->Id)
2345 {
2346 case 64:
2347 case 61:
2348 case 1101:
2349 case 66:
2350 case 648:
2351 case 2301:
2352 case 1061:
2353 case 1261:
2354 case 629:
2355 case 181:
2356 case 715:
2357 case 1562:
2358 case 833:
2359 case 1161:
2360 case 713: // xinef, bloodworms
2361 numSummons = (damage > 0) ? damage : 1;
2362 break;
2363 default:
2364 numSummons = 1;
2365 break;
2366 }
2367
2368 switch (properties->Category)
2369 {
2373 if (properties->Flags & 512)
2374 {
2375 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2376 break;
2377 }
2378 switch (properties->Type)
2379 {
2380 case SUMMON_TYPE_PET:
2383 case SUMMON_TYPE_MINION:
2384 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2385 break;
2386 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2389 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2390 break;
2392 case SUMMON_TYPE_TOTEM:
2393 {
2394 // protection code
2395 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2396 if (!summon || !summon->IsTotem())
2397 return;
2398
2399 // Mana Tide Totem
2400 if (m_spellInfo->Id == 16190)
2402
2403 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2404 {
2405 summon->SetMaxHealth(damage);
2406 summon->SetHealth(damage);
2407 }
2408 break;
2409 }
2410 case SUMMON_TYPE_JEEVES:
2412 {
2413 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2414 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2415 return;
2416
2417 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2419
2420 summon->SetImmuneToAll(true);
2422
2423 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2424 //summon->AI()->EnterEvadeMode();
2425 if (properties->Type != SUMMON_TYPE_JEEVES)
2426 {
2427 summon->GetMotionMaster()->Clear(false);
2429 }
2430 break;
2431 }
2432 default:
2433 {
2434 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2435
2436 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2437
2438 for (uint32 count = 0; count < numSummons; ++count)
2439 {
2440 Position pos;
2441 if (count == 0)
2442 pos = *destTarget;
2443 else
2444 // randomize position for multiple summons
2445 pos = m_caster->GetRandomPoint(*destTarget, radius);
2446
2447 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2448 if (!summon)
2449 continue;
2450
2451 summon->SetTempSummonType(summonType);
2452
2453 if (properties->Category == SUMMON_CATEGORY_ALLY)
2454 {
2457 }
2458
2459 ExecuteLogEffectSummonObject(effIndex, summon);
2460 }
2461 return;
2462 }
2463 }//switch
2464 break;
2466 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2467 if (m_originalCaster)
2469 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2470 break;
2472 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2473 break;
2475 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2476 // to cast a ride vehicle spell on the summoned unit.
2477 //float x, y, z;
2478 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2479 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2480 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2482
2483 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2484 if (!summon || !summon->IsVehicle())
2485 return;
2486
2487 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2489 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2490 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2491 {
2492 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2493 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2494 spellId = spellInfo->Id;
2495 }
2496
2497 // xinef: if we have small value, it indicates seat position
2498 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2499 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2500 else
2501 m_originalCaster->CastSpell(summon, spellId, true);
2502
2503 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2504 //uint32 faction = properties->Faction;
2505 //if (!faction)
2506 uint32 faction = m_originalCaster->GetFaction();
2507
2508 summon->SetFaction(faction);
2509 break;
2510 }
2511
2512 if (summon)
2513 {
2515 ExecuteLogEffectSummonObject(effIndex, summon);
2516 }
2517}
@ MOTION_SLOT_ACTIVE
Definition: MotionMaster.h:62
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition: VehicleDefines.h:52
@ REACT_PASSIVE
Definition: Unit.h:548
@ UNIT_MASK_MINION
Definition: UnitDefines.h:136
NPCFlags
Non Player Character flags.
Definition: UnitDefines.h:292
TempSummonType
Definition: Object.h:44
@ TEMPSUMMON_DEAD_DESPAWN
Definition: Object.h:51
@ SPELL_AURA_CONTROL_VEHICLE
Definition: SpellAuraDefines.h:299
@ SUMMON_TYPE_VEHICLE2
Definition: SharedDefines.h:3304
@ SUMMON_TYPE_LIGHTWELL
Definition: SharedDefines.h:3305
@ SUMMON_TYPE_MINION
Definition: SharedDefines.h:3297
@ SUMMON_TYPE_GUARDIAN
Definition: SharedDefines.h:3296
@ SUMMON_TYPE_JEEVES
Definition: SharedDefines.h:3306
@ SUMMON_TYPE_PET
Definition: SharedDefines.h:3295
@ SUMMON_TYPE_TOTEM
Definition: SharedDefines.h:3298
@ SUMMON_TYPE_VEHICLE
Definition: SharedDefines.h:3303
@ SUMMON_TYPE_MINIPET
Definition: SharedDefines.h:3299
@ SUMMON_TYPE_GUARDIAN2
Definition: SharedDefines.h:3300
@ SUMMON_CATEGORY_VEHICLE
Definition: SharedDefines.h:3287
@ SUMMON_CATEGORY_ALLY
Definition: SharedDefines.h:3284
@ SUMMON_CATEGORY_WILD
Definition: SharedDefines.h:3283
@ SUMMON_CATEGORY_UNK
Definition: SharedDefines.h:3288
#define MAX_VEHICLE_SEATS
Definition: DBCStructure.h:2023
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition: DBCEnums.h:428
void SelectLevel(bool changelevel=true)
Definition: Creature.cpp:1509
uint32 npcflag
Definition: CreatureData.h:200
void SetTempSummonType(TempSummonType type)
Definition: TemporarySummon.cpp:277
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition: Object.cpp:1502
void SetFaction(uint32 faction)
Definition: Unit.cpp:10017
virtual float GetFollowAngle() const
Definition: Unit.h:1722
void SetOwnerGUID(ObjectGuid owner)
Definition: Unit.cpp:10534
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:677
void SetMaxHealth(uint32 val)
Definition: Unit.cpp:15482
void SetCreatorGUID(ObjectGuid creator)
Definition: Unit.h:1225
void ReplaceAllNpcFlags(NPCFlags flags)
Definition: Unit.h:697
void RemoveAllMinionsByEntry(uint32 entry)
Definition: Unit.cpp:10819
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition: Unit.h:810
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, bool visibleBySummonerOnly=false)
Definition: Object.cpp:2163
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true)
The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition: MotionMaster.cpp:409
void Clear(bool reset=true)
Definition: MotionMaster.h:165
uint32 Flags
Definition: DBCStructure.h:1914
uint32 Type
Definition: DBCStructure.h:1912
uint32 Id
Definition: DBCStructure.h:1909

References Unit::CastCustomSpell(), Unit::CastSpell(), SummonPropertiesEntry::Category, MotionMaster::Clear(), Unit::CountPctFromMaxHealth(), damage, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), SummonPropertiesEntry::Flags, Creature::GetCreatureTemplate(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), Position::GetPositionZ(), WorldObject::GetRandomPoint(), Unit::GetSpellModOwner(), SpellInfo::HasAura(), Unit::HasUnitTypeMask(), SpellInfo::Id, SummonPropertiesEntry::Id, Unit::IsTotem(), Unit::IsVehicle(), LOG_ERROR, m_caster, m_originalCaster, Position::m_positionZ, m_spellInfo, MAX_VEHICLE_SEATS, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), CreatureTemplate::npcflag, PET_FOLLOW_DIST, REACT_PASSIVE, Unit::RemoveAllMinionsByEntry(), Unit::ReplaceAllNpcFlags(), Creature::SelectLevel(), Unit::SetCreatorGUID(), Unit::SetFaction(), Unit::SetHealth(), Unit::SetImmuneToAll(), Unit::SetMaxHealth(), Unit::SetOwnerGUID(), Creature::SetReactState(), TempSummon::SetTempSummonType(), SPELL_AURA_CONTROL_VEHICLE, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, SPELLVALUE_BASE_POINT0, sSpellMgr, sSummonPropertiesStore, SUMMON_CATEGORY_ALLY, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, SUMMON_CATEGORY_UNK, SUMMON_CATEGORY_VEHICLE, SUMMON_CATEGORY_WILD, SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER, SUMMON_TYPE_GUARDIAN, SUMMON_TYPE_GUARDIAN2, SUMMON_TYPE_JEEVES, SUMMON_TYPE_LIGHTWELL, SUMMON_TYPE_MINION, SUMMON_TYPE_MINIPET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, SUMMON_TYPE_VEHICLE, SUMMON_TYPE_VEHICLE2, Map::SummonCreature(), WorldObject::SummonCreature(), SummonGuardian(), TEMPSUMMON_DEAD_DESPAWN, TEMPSUMMON_TIMED_DESPAWN, SummonPropertiesEntry::Type, UNIT_MASK_MINION, and VEHICLE_SPELL_RIDE_HARDCODED.

◆ EffectTameCreature()

void Spell::EffectTameCreature ( SpellEffIndex  effIndex)
3063{
3065 return;
3066
3067 if (m_caster->GetPetGUID())
3068 return;
3069
3070 if (!unitTarget)
3071 return;
3072
3073 if (!unitTarget->IsCreature())
3074 return;
3075
3076 Creature* creatureTarget = unitTarget->ToCreature();
3077
3078 if (creatureTarget->IsPet())
3079 return;
3080
3082 return;
3083
3084 // cast finish successfully
3085 //SendChannelUpdate(0);
3086 finish();
3087
3088 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3089 if (!pet) // in very specific state like near world end/etc.
3090 return;
3091
3092 // "kill" original creature
3093 creatureTarget->DespawnOrUnsummon();
3094
3095 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3096
3097 // prepare visual effect for levelup
3098 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3099
3100 // add to world
3101 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3102
3103 // visual effect for levelup
3104 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3105
3106 // caster have pet now
3107 m_caster->SetMinion(pet, true);
3108
3109 pet->InitTalentForLevel();
3110
3111 if (m_caster->IsPlayer())
3112 {
3115 }
3116}
@ UNIT_FIELD_LEVEL
Definition: UpdateFields.h:114

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), Creature::DespawnOrUnsummon(), effectHandleMode, finish(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), Unit::SetUInt32Value(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_LEVEL, and unitTarget.

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3259{
3261 return;
3262
3263 if (!unitTarget)
3264 return;
3265
3266 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3267 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3268 {
3269 m_caster->CastSpell(unitTarget, 67485, true);
3271 }
3272
3273 // this effect use before aura Taunt apply for prevent taunt already attacking target
3274 // for spell as marked "non effective at already attacking target"
3276 {
3278 return;
3279 }
3280
3282 {
3283 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3284 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3286 if (topThreat > myThreat)
3287 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3288
3289 //Set aggro victim to caster
3291 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3292 }
3293}
@ SPELL_AURA_MOD_TAUNT
Definition: SpellAuraDefines.h:74
Definition: ThreatMgr.h:49
float GetThreat() const
Definition: ThreatMgr.h:63
HostileReference * getMostHated() const
Definition: ThreatMgr.h:169
HostileReference * getReferenceByTarget(Unit const *victim) const
Definition: ThreatMgr.cpp:261
bool empty() const
Definition: ThreatMgr.h:164
void setCurrentVictim(HostileReference *hostileRef)
Definition: ThreatMgr.cpp:572
void DoAddThreat(Unit *victim, float threat)
Definition: ThreatMgr.cpp:453
float GetThreat(Unit *victim, bool alsoSearchOfflineList=false)
Definition: ThreatMgr.cpp:525
ThreatContainer & GetOnlineContainer()
Definition: ThreatMgr.h:276
bool CanHaveThreatList() const
Definition: Unit.cpp:14568

References Unit::CanHaveThreatList(), Unit::CastSpell(), Unit::CombatStart(), ThreatMgr::DoAddThreat(), effectHandleMode, ThreatContainer::empty(), ThreatContainer::getMostHated(), ThreatMgr::GetOnlineContainer(), ThreatContainer::getReferenceByTarget(), HostileReference::GetThreat(), ThreatMgr::GetThreat(), Unit::GetThreatMgr(), Unit::GetVictim(), SpellInfo::HasAura(), SpellInfo::Id, m_caster, m_spellInfo, SendCastResult(), ThreatMgr::setCurrentVictim(), SPELL_AURA_MOD_TAUNT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_DONT_REPORT, and unitTarget.

◆ EffectTeleportUnits()

void Spell::EffectTeleportUnits ( SpellEffIndex  effIndex)
1169{
1171 return;
1172
1173 if (!unitTarget || unitTarget->IsInFlight())
1174 return;
1175
1176 if (unitTarget->IsPlayer())
1177 {
1178 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
1179 }
1180
1181 // Pre effects
1182 switch (m_spellInfo->Id)
1183 {
1184 case 70746: // Teleport Into Sunwell (for Battered Hilt)
1185 if (Player* target = unitTarget->ToPlayer())
1186 {
1187 uint32 mapid = destTarget->GetMapId();
1188 float x, y, z, orientation;
1189 destTarget->GetPosition(x, y, z, orientation);
1190 target->TeleportTo(mapid, x, y, z, orientation, TELE_TO_GM_MODE); // skip PlayerCannotEnter check
1191 }
1192 return;
1193 }
1194
1195 // If not exist data for dest location - return
1196 if (!m_targets.HasDst())
1197 {
1198 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - does not have destination for spell ID {}\n", m_spellInfo->Id);
1199 return;
1200 }
1201
1202 // Init dest coordinates
1203 uint32 mapid = destTarget->GetMapId();
1204 if (mapid == MAPID_INVALID)
1205 mapid = unitTarget->GetMapId();
1206 float x, y, z, orientation;
1207 destTarget->GetPosition(x, y, z, orientation);
1208 if (!orientation && m_targets.GetUnitTarget())
1209 orientation = m_targets.GetUnitTarget()->GetOrientation();
1210 LOG_DEBUG("spells.aura", "Spell::EffectTeleportUnits - teleport unit to {} {} {} {} {}\n", mapid, x, y, z, orientation);
1211
1212 if (mapid == unitTarget->GetMapId())
1213 {
1214 if (unitTarget->GetVehicleKit()) // we are vehicle!
1215 unitTarget->GetVehicleKit()->TeleportVehicle(x, y, z, orientation);
1216 else
1217 {
1219 unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster, false, withPet, true);
1220 if (unitTarget->IsPlayer()) // pussywizard: for units it's done inside NearTeleportTo
1222 }
1223 }
1224 else if (unitTarget->IsPlayer())
1225 unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL : 0);
1226 else
1227 {
1228 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
1229 return;
1230 }
1231
1232 // post effects for TARGET_DEST_DB
1233 switch (m_spellInfo->Id)
1234 {
1235 // Dimensional Ripper - Everlook
1236 case 23442:
1237 {
1238 int32 r = irand(0, 119);
1239 if (r >= 70) // 7/12 success
1240 {
1241 if (r < 100) // 4/12 evil twin
1242 m_caster->CastSpell(m_caster, 23445, true);
1243 else // 1/12 fire
1244 m_caster->CastSpell(m_caster, 23449, true);
1245 }
1246 return;
1247 }
1248 // Ultrasafe Transporter: Toshley's Station
1249 case 36941:
1250 {
1251 if (roll_chance_i(50)) // 50% success
1252 {
1253 int32 rand_eff = urand(1, 7);
1254 switch (rand_eff)
1255 {
1256 case 1:
1257 // soul split - evil
1258 m_caster->CastSpell(m_caster, 36900, true);
1259 break;
1260 case 2:
1261 // soul split - good
1262 m_caster->CastSpell(m_caster, 36901, true);
1263 break;
1264 case 3:
1265 // Increase the size
1266 m_caster->CastSpell(m_caster, 36895, true);
1267 break;
1268 case 4:
1269 // Decrease the size
1270 m_caster->CastSpell(m_caster, 36893, true);
1271 break;
1272 case 5:
1273 // Transform
1274 {
1276 m_caster->CastSpell(m_caster, 36897, true);
1277 else
1278 m_caster->CastSpell(m_caster, 36899, true);
1279 break;
1280 }
1281 case 6:
1282 // chicken
1283 m_caster->CastSpell(m_caster, 36940, true);
1284 break;
1285 case 7:
1286 // evil twin
1287 m_caster->CastSpell(m_caster, 23445, true);
1288 break;
1289 }
1290 }
1291 return;
1292 }
1293 }
1294}
#define MAPID_INVALID
Definition: Position.h:248
@ TELE_TO_SPELL
Definition: Player.h:825
@ TELE_TO_GM_MODE
Definition: Player.h:821
TeamId GetTeamId(bool original=false) const
Definition: Player.h:2090
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition: Player.cpp:1330
Vehicle * GetVehicleKit() const
Definition: Unit.h:1686
void TeleportVehicle(float x, float y, float z, float ang)
Definition: Vehicle.cpp:545

References Unit::CastSpell(), destTarget, effectHandleMode, Position::GetExactDist(), WorldObject::GetMap(), WorldLocation::GetMapId(), Position::GetOrientation(), Position::GetPosition(), Player::GetTeamId(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), SpellCastTargets::HasDst(), SpellInfo::Id, irand(), Map::IsDungeon(), Unit::IsInFlight(), Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_spellInfo, m_targets, MAPID_INVALID, Unit::NearTeleportTo(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, sScriptMgr, TEAM_ALLIANCE, TELE_TO_GM_MODE, TELE_TO_SPELL, Player::TeleportTo(), Vehicle::TeleportVehicle(), Object::ToPlayer(), unitTarget, Unit::UpdateObjectVisibility(), and urand().

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3648{
3650 return;
3651
3652 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3653 return;
3654
3655 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3657 return;
3658
3660}
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition: Unit.cpp:14607

References Unit::AddThreat(), Unit::CanHaveThreatList(), damage, effectHandleMode, Unit::IsAlive(), Unit::IsFriendlyTo(), m_caster, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectTitanGrip()

void Spell::EffectTitanGrip ( SpellEffIndex  effIndex)
5866{
5868 return;
5869
5870 if (m_caster->IsPlayer())
5871 {
5872 if (Aura* aur = m_caster->GetAura(49152))
5873 aur->RecalculateAmountOfEffects();
5874 else
5875 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5876
5878 }
5879}
void SetCanTitanGrip(bool value)
Definition: Player.cpp:13145

References Unit::CastSpell(), effectHandleMode, Unit::GetAura(), Object::IsPlayer(), m_caster, Player::SetCanTitanGrip(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and unitTarget.

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2800{
2802 return;
2803
2804 if (!m_caster->IsPlayer())
2805 return;
2806 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2807 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2808 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2809}

References effectHandleMode, Object::IsPlayer(), m_caster, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectTransmitted()

void Spell::EffectTransmitted ( SpellEffIndex  effIndex)
5340{
5342 return;
5343
5344 uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
5345
5346 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
5347
5348 if (!goinfo)
5349 {
5350 LOG_ERROR("sql.sql", "Gameobject (Entry: {}) not exist and not created at spell (ID: {}) cast", name_id, m_spellInfo->Id);
5351 return;
5352 }
5353
5354 float fx, fy, fz;
5355
5356 if (m_targets.HasDst())
5357 destTarget->GetPosition(fx, fy, fz);
5358 //FIXME: this can be better check for most objects but still hack
5359 else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
5360 {
5361 float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
5363 }
5364 else
5365 {
5366 //GO is always friendly to it's creator, get range for friends
5367 float min_dis = m_spellInfo->GetMinRange(true);
5368 float max_dis = m_spellInfo->GetMaxRange(true);
5369 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
5370
5372 }
5373
5374 // Seaforium charge
5375 if (m_spellInfo->Id == 52410 || m_spellInfo->Id == 66268 || m_spellInfo->Id == 66674) // SotA / IoC / IoC Huge
5376 {
5377 fx = m_caster->GetPositionX();
5378 fy = m_caster->GetPositionY();
5379 fz = m_caster->GetPositionZ();
5380 }
5381
5382 Map* cMap = m_caster->GetMap();
5383
5384 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject();
5385
5386 if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
5387 {
5388 delete pGameObj;
5389 return;
5390 }
5391
5392 int32 duration = m_spellInfo->GetDuration();
5393
5394 switch (goinfo->type)
5395 {
5397 {
5399 m_caster->AddGameObject(pGameObj); // will removed at spell cancel
5400
5401 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
5402 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
5403 int32 lastSec = 0;
5404 switch (urand(0, 2))
5405 {
5406 case 0:
5407 lastSec = 3;
5408 break;
5409 case 1:
5410 lastSec = 7;
5411 break;
5412 case 2:
5413 lastSec = 13;
5414 break;
5415 }
5416
5417 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
5418 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
5419
5420 break;
5421 }
5423 {
5424 if (m_caster->IsPlayer())
5425 {
5426 pGameObj->AddUniqueUse(m_caster->ToPlayer());
5427 m_caster->AddGameObject(pGameObj); // will be removed at spell cancel
5428 }
5429 break;
5430 }
5431 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
5432 m_caster->AddGameObject(pGameObj);
5433 break;
5436 default:
5437 break;
5438 }
5439
5440 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5441
5442 pGameObj->SetOwnerGUID(m_caster->GetGUID());
5443
5444 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
5445 pGameObj->SetSpellId(m_spellInfo->Id);
5446
5447 ExecuteLogEffectSummonObject(effIndex, pGameObj);
5448
5449 LOG_DEBUG("spells.effect", "AddObject at SpellEfects.cpp EffectTransmitted");
5450 //m_caster->AddGameObject(pGameObj);
5451 //m_ObjToDel.push_back(pGameObj);
5452
5453 cMap->AddToMap(pGameObj, true);
5454
5455 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
5456 {
5457 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5458 linkedTrap->SetSpellId(m_spellInfo->Id);
5459 linkedTrap->SetOwnerGUID(m_caster->GetGUID());
5460
5461 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
5462 }
5463
5464 if (Player* player = m_caster->ToPlayer())
5465 {
5466 player->SetCanTeleport(true);
5467 }
5468}
@ UNIT_FIELD_CHANNEL_OBJECT
Definition: UpdateFields.h:93
#define FISHING_BOBBER_READY_TIME
Definition: GameObject.h:118
@ GAMEOBJECT_TYPE_DUEL_ARBITER
Definition: SharedDefines.h:1576
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition: SharedDefines.h:1578
@ GAMEOBJECT_TYPE_CHEST
Definition: SharedDefines.h:1563
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition: SharedDefines.h:1585
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition: SharedDefines.h:1577
void SetOwnerGUID(ObjectGuid owner)
Definition: GameObject.h:164
void AddUniqueUse(Player *player)
Definition: GameObject.cpp:927
float GetMinRange(bool positive=false) const
Definition: SpellInfo.cpp:2313

References Unit::AddGameObject(), Map::AddToMap(), GameObject::AddUniqueUse(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), FISHING_BOBBER_READY_TIME, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DUEL_ARBITER, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, GAMEOBJECT_TYPE_SUMMONING_RITUAL, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_originalCaster, m_spellInfo, m_targets, rand_norm(), Object::SetGuidValue(), GameObject::SetOwnerGUID(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SpellInfo::Speed, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), GameObjectTemplate::type, UNIT_FIELD_CHANNEL_OBJECT, and urand().

◆ EffectTriggerMissileSpell()

void Spell::EffectTriggerMissileSpell ( SpellEffIndex  effIndex)
947{
950 return;
951
952 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
953
954 // normal case
955 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
956 if (!spellInfo)
957 {
958 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
959 return;
960 }
961
962 SpellCastTargets targets;
964 {
965 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
966 return;
967 targets.SetUnitTarget(unitTarget);
968 }
969 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
970 {
971 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
972 return;
973
975 targets.SetDst(m_targets);
976
977 targets.SetUnitTarget(m_caster);
978 }
979
980 CustomSpellValues values;
981 // set basepoints for trigger with value effect
983 {
984 // maybe need to set value only when basepoints == 0?
988 }
989
990 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
991 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
992 {
993 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
994 }
995
996 // original caster guid only for GO cast
997 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
998}
@ TARGET_FLAG_DEST_LOCATION
Definition: SpellInfo.h:52
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
Definition: SharedDefines.h:926
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell, uint8 effIndex=MAX_SPELL_EFFECTS) const
Definition: SpellInfo.cpp:1037
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:349

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), SpellInfo::GetExplicitTargetMask(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, SpellInfo::NeedsToBeTriggeredByCaster(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectTriggerRitualOfSummoning()

void Spell::EffectTriggerRitualOfSummoning ( SpellEffIndex  effIndex)
1055{
1057 return;
1058
1059 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1060 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1061
1062 if (!spellInfo)
1063 {
1064 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1065 return;
1066 }
1067
1068 finish();
1069
1070 m_caster->CastSpell((Unit*)nullptr, spellInfo, true);
1071}

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, finish(), SpellInfo::Id, LOG_ERROR, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, and sSpellMgr.

◆ EffectTriggerSpell()

void Spell::EffectTriggerSpell ( SpellEffIndex  effIndex)
Todo:
: move those to spell scripts
790{
793 return;
794
795 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
796
798 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
800 {
801 // special cases
802 switch (triggered_spell_id)
803 {
804 // Mirror Image
805 case 58832:
806 {
807 // Glyph of Mirror Image
808 if (m_caster->HasAura(63093))
809 m_caster->CastSpell(m_caster, 65047, true); // Mirror Image
810
811 break;
812 }
813 // Demonic Empowerment -- succubus
814 case 54437:
815 {
819
820 // Cast Lesser Invisibility
821 unitTarget->CastSpell(unitTarget, 7870, true);
822 return;
823 }
824 // just skip
825 case 23770: // Sayge's Dark Fortune of *
826 // not exist, common cooldown can be implemented in scripts if need.
827 return;
828 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
829 case 29284:
830 {
831 // Brittle Armor
832 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
833 if (!spell)
834 return;
835
836 for (uint32 j = 0; j < spell->StackAmount; ++j)
837 m_caster->CastSpell(unitTarget, spell->Id, true);
838 return;
839 }
840 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
841 case 29286:
842 {
843 // Mercurial Shield
844 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
845 if (!spell)
846 return;
847
848 for (uint32 j = 0; j < spell->StackAmount; ++j)
849 m_caster->CastSpell(unitTarget, spell->Id, true);
850 return;
851 }
852 // Cloak of Shadows
853 case 35729:
854 {
857 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
858 {
859 // remove all harmful spells on you...
860 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
861
862 // Pounce Bleed shouldn't be removed by Cloak of Shadows.
863 if (spell->GetAllEffectsMechanicMask() & 1 << MECHANIC_BLEED)
864 return;
865
866 bool dmgClassNone = false;
868 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
869 {
870 if ((iter->second->GetEffectMask() & (1 << i)) &&
871 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE &&
872 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
873 spell->Effects[i].ApplyAuraName != SPELL_AURA_DUMMY)
874 {
875 dmgClassNone = false;
876 break;
877 }
878 dmgClassNone = true;
879 }
880
881 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC || (spell->GetDispelMask() & dispelMask) || dmgClassNone) &&
882 // ignore positive and passive auras
883 !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive() &&
884 // Xinef: Ignore NPC spells having INVULNERABILITY attribute
886 {
887 m_caster->RemoveAura(iter);
888 }
889 else
890 ++iter;
891 }
892 return;
893 }
894 }
895 }
896
897 // normal case
898 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
899 if (!spellInfo)
900 {
901 LOG_DEBUG("spells.aura", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
902 return;
903 }
904
905 SpellCastTargets targets;
907 {
908 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
909 return;
910 targets.SetUnitTarget(unitTarget);
911 }
912 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
913 {
914 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
915 return;
916
918 targets.SetDst(m_targets);
919
920 if (Unit* target = m_targets.GetUnitTarget())
921 targets.SetUnitTarget(target);
922 else
923 targets.SetUnitTarget(m_caster);
924 }
925
926 CustomSpellValues values;
927 // set basepoints for trigger with value effect
929 {
930 // maybe need to set value only when basepoints == 0?
934 }
935
936 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
937 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
938 {
939 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
940 }
941
942 // original caster guid only for GO cast
944}
@ SPELL_AURA_MOD_STALKED
Definition: SpellAuraDefines.h:131
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:86
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition: SharedDefines.h:920
@ SPELL_EFFECT_TRIGGER_SPELL
Definition: SharedDefines.h:842
@ MECHANIC_BLEED
Definition: SharedDefines.h:1340
@ DISPEL_ALL
Definition: SharedDefines.h:1379

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, DISPEL_ALL, SpellInfo::DmgClass, EFFECT_0, effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), SpellInfo::GetCategory(), SpellInfo::GetDispelMask(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, MECHANIC_BLEED, SpellInfo::NeedsToBeTriggeredByCaster(), Unit::RemoveAura(), Unit::RemoveAurasByType(), Unit::RemoveMovementImpairingAuras(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_ATTR0_NO_IMMUNITIES, SPELL_AURA_DUMMY, SPELL_AURA_MOD_STALKED, SPELL_AURA_MOD_STUN, SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_TRIGGER_SPELL, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, SpellInfo::StackAmount, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_NO_PERIODIC_RESET, and unitTarget.

◆ EffectUnlearnSpecialization()

void Spell::EffectUnlearnSpecialization ( SpellEffIndex  effIndex)
1319{
1321 return;
1322
1323 if (!unitTarget)
1324 return;
1325
1326 Player* player = unitTarget->ToPlayer();
1327 if (!player)
1328 {
1329 return;
1330 }
1331
1332 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1333
1334 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1335 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1336 player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1337}
#define SPEC_MASK_ALL
Definition: Player.h:177
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition: Player.cpp:3312

References effectHandleMode, SpellInfo::Effects, Object::GetGUID(), LOG_DEBUG, m_caster, m_spellInfo, Player::removeSpell(), SPEC_MASK_ALL, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectUntrainTalents()

void Spell::EffectUntrainTalents ( SpellEffIndex  effIndex)
2724{
2726 return;
2727
2728 if (!unitTarget || m_caster->IsPlayer())
2729 return;
2730
2731 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2733}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition: Player.cpp:8878

References effectHandleMode, Object::GetGUID(), Object::IsPlayer(), m_caster, Player::SendTalentWipeConfirm(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectUnused()

void Spell::EffectUnused ( SpellEffIndex  effIndex)
248{
249 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
250}

◆ EffectWeaponDmg()

void Spell::EffectWeaponDmg ( SpellEffIndex  effIndex)
3296{
3298 return;
3299
3300 if (!unitTarget || !unitTarget->IsAlive())
3301 return;
3302
3303 // multiple weapon dmg effect workaround
3304 // execute only the last weapon damage
3305 // and handle all effects at once
3306 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
3307 {
3308 switch (m_spellInfo->Effects[j].Effect)
3309 {
3314 return; // we must calculate only at last weapon effect
3315 break;
3316 }
3317 }
3318
3319 // some spell specific modifiers
3320 float totalDamagePercentMod = 100.0f; // applied to final bonus+weapon damage
3321 int32 spell_bonus = 0; // bonus specific for spell
3322 bool normalized = false;
3323
3325 {
3327 {
3328 switch (m_spellInfo->Id)
3329 {
3330 // Trial of the Champion, Black Knight, Obliterate
3331 case 67725:
3332 case 67883:
3333 {
3334 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), 1) * 30.0f);
3335 break;
3336 }
3337 }
3338 break;
3339 }
3341 {
3342 // Devastate (player ones)
3343 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
3344 {
3345 m_caster->CastSpell(unitTarget, 58567, true);
3346
3347 if (Aura* aur = unitTarget->GetAura(58567))
3348 {
3349 // 58388 - Glyph of Devastate dummy aura.
3350 if (m_caster->HasAura(58388))
3351 aur->ModStackAmount(1);
3352
3353 spell_bonus += (aur->GetStackAmount() - 1) * CalculateSpellDamage(2, unitTarget);
3354 }
3355 }
3356 break;
3357 }
3358 case SPELLFAMILY_ROGUE:
3359 {
3360 // Fan of Knives, Hemorrhage, Ghostly Strike
3361 if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
3362 || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
3363 {
3364 // Hemorrhage
3365 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
3366 {
3368 }
3369 // 50% more damage with daggers
3370 if (m_caster->IsPlayer())
3371 if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
3372 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
3373 AddPct(totalDamagePercentMod, 50.0f);
3374 }
3375 // Mutilate (for each hand)
3376 else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
3377 {
3378 bool found = false;
3379 // fast check
3381 found = true;
3382 // full aura scan
3383 else
3384 {
3386 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3387 {
3388 if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
3389 {
3390 found = true;
3391 break;
3392 }
3393 }
3394 }
3395
3396 if (found)
3397 AddPct(totalDamagePercentMod, 20.0f); // 120% if poisoned
3398 }
3399 break;
3400 }
3402 {
3403 switch (m_spellInfo->Id)
3404 {
3405 case 20467: // Seal of Command Unleashed
3406 spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3408 break;
3409 case 42463: // Seals of the Pure for Seal of Vengeance/Corruption
3410 case 53739:
3412 AddPct(totalDamagePercentMod, sealsOfPure->GetAmount());
3413 break;
3414 case 53385: // Divine Storm deals normalized damage
3415 normalized = true;
3416 break;
3417 default:
3418 break;
3419 }
3420 break;
3421 }
3422 case SPELLFAMILY_SHAMAN:
3423 {
3424 // Skyshatter Harness item set bonus
3425 // Stormstrike
3426 if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634))
3427 m_caster->CastSpell(m_caster, 38430, true, nullptr, aurEff);
3428 // Lava lash damage increased by Flametongue weapon
3430 AddPct(totalDamagePercentMod, 25.0f);
3431 break;
3432 }
3433 case SPELLFAMILY_DRUID:
3434 {
3435 // Mangle (Cat): CP
3436 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
3437 {
3439 }
3440 // Shred, Maul - Rend and Tear
3442 {
3443 if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
3444 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
3445 }
3446 break;
3447 }
3448 case SPELLFAMILY_HUNTER:
3449 {
3450 // Kill Shot
3451 if (m_spellInfo->SpellFamilyFlags[1] & 0x800000)
3452 {
3453 spell_bonus += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.4f);
3454 }
3455 break;
3456 }
3458 {
3459 // Plague Strike
3460 if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
3461 {
3462 // Glyph of Plague Strike
3463 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(58657, EFFECT_0))
3464 AddPct(totalDamagePercentMod, aurEff->GetAmount());
3465 break;
3466 }
3467 // Blood Strike
3468 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
3469 {
3470 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3471 //Death Knight T8 Melee 4P Bonus
3472 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3473 AddPct(disease_amt, aurEff->GetAmount());
3474
3475 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f);
3476
3477 // Glyph of Blood Strike
3478 if (m_caster->GetAuraEffect(59332, EFFECT_0))
3480 AddPct(totalDamagePercentMod, 20.0f);
3481 break;
3482 }
3483 // Death Strike
3484 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
3485 {
3486 // Glyph of Death Strike
3487 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
3488 if (uint32 runic = std::min<uint32>(m_caster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
3489 AddPct(totalDamagePercentMod, runic);
3490 break;
3491 }
3492 // Obliterate (12.5% more damage per disease)
3493 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
3494 {
3495 bool consumeDiseases = true;
3496 // Annihilation
3498 // Do not consume diseases if roll sucesses
3499 if (roll_chance_i(aurEff->GetAmount()))
3500 consumeDiseases = false;
3501
3502 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3503 //Death Knight T8 Melee 4P Bonus
3504 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3505 AddPct(disease_amt, aurEff->GetAmount());
3506
3507 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f);
3508 break;
3509 }
3510 // Blood-Caked Strike - Blood-Caked Blade
3511 if (m_spellInfo->SpellIconID == 1736)
3512 {
3513 int32 weaponDamage = m_caster->CalculateDamage(m_attackType, false, true);
3514 ApplyPct(weaponDamage, std::min(uint32(3), unitTarget->GetDiseasesByCaster(m_caster->GetGUID())) * 12.5f);
3515 spell_bonus = weaponDamage;
3516 break;
3517 }
3518 // Heart Strike
3519 if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
3520 {
3521 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3522 //Death Knight T8 Melee 4P Bonus
3523 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3524 AddPct(disease_amt, aurEff->GetAmount());
3525
3526 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()));
3527 break;
3528 }
3529 // Rune Strike
3530 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000000)
3531 {
3532 spell_bonus += int32(0.15f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3533 }
3534
3535 break;
3536 }
3537 }
3538
3539 float weaponDamagePercentMod = 100.0f;
3540 int32 fixed_bonus = 0;
3541
3542 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3543 {
3544 switch (m_spellInfo->Effects[j].Effect)
3545 {
3548 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3549 break;
3551 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3552 normalized = true;
3553 break;
3555 ApplyPct(weaponDamagePercentMod, CalculateSpellDamage(j, unitTarget));
3556 break;
3557 default:
3558 break; // not weapon damage effect, just skip
3559 }
3560 }
3561
3562 // apply to non-weapon bonus weapon total pct effect, weapon total flat effect included in weapon damage
3563 if (fixed_bonus || spell_bonus)
3564 {
3565 UnitMods unitMod;
3566 switch (m_attackType)
3567 {
3568 default:
3569 case BASE_ATTACK:
3570 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
3571 break;
3572 case OFF_ATTACK:
3573 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
3574 break;
3575 case RANGED_ATTACK:
3576 unitMod = UNIT_MOD_DAMAGE_RANGED;
3577 break;
3578 }
3579
3581 {
3582 float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
3583 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
3584 spell_bonus = int32(spell_bonus * weapon_total_pct);
3585 }
3586 }
3587
3588 int32 weaponDamage = 0;
3589 // Dancing Rune Weapon
3590 if (m_caster->GetEntry() == 27893)
3591 {
3592 if (Unit* owner = m_caster->GetOwner())
3593 weaponDamage = owner->CalculateDamage(m_attackType, normalized, true);
3594 }
3595 else if (m_spellInfo->Id == 5019) // Wands
3596 {
3597 weaponDamage = m_caster->CalculateDamage(m_attackType, true, false);
3598 }
3599 else
3600 {
3601 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, true);
3602 }
3603
3604 // Sequence is important
3605 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3606 {
3607 // We assume that a spell have at most one fixed_bonus
3608 // and at most one weaponDamagePercentMod
3609 switch (m_spellInfo->Effects[j].Effect)
3610 {
3614 weaponDamage += fixed_bonus;
3615 break;
3617 ApplyPct(weaponDamage, weaponDamagePercentMod);
3618 default:
3619 break; // not weapon damage effect, just skip
3620 }
3621 }
3622
3623 weaponDamage += spell_bonus;
3624 ApplyPct(weaponDamage, totalDamagePercentMod);
3625
3626 // prevent negative damage
3627 uint32 eff_damage(std::max(weaponDamage, 0));
3628
3629 // Add melee damage bonuses (also check for negative)
3632
3633 // Meteor like spells (divided damage to targets)
3635 {
3636 uint32 count = 0;
3637 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3638 if (ihit->effectMask & (1 << effIndex))
3639 ++count;
3640
3641 eff_damage /= count; // divide to all targets
3642 }
3643
3644 m_damage += eff_damage;
3645}
UnitMods
Definition: Unit.h:142
@ UNIT_MOD_DAMAGE_OFFHAND
Definition: Unit.h:166
@ UNIT_MOD_DAMAGE_RANGED
Definition: Unit.h:167
@ UNIT_MOD_DAMAGE_MAINHAND
Definition: Unit.h:165
@ TOTAL_PCT
Definition: Unit.h:129
@ ITEM_SUBCLASS_WEAPON_DAGGER
Definition: ItemTemplate.h:359
@ SPELL_AURA_ADD_PCT_MODIFIER
Definition: SpellAuraDefines.h:171
@ POWER_RUNIC_POWER
Definition: SharedDefines.h:275
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition: SharedDefines.h:899
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition: SharedDefines.h:809
@ AURA_STATE_DEADLY_POISON
Definition: SharedDefines.h:1308
@ AURA_STATE_BLEEDING
Definition: SharedDefines.h:1310
@ DISPEL_POISON
Definition: SharedDefines.h:1376
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:13232
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode=0)
Definition: Unit.cpp:5791
AuraEffect * GetAuraEffectDummy(uint32 spellid) const
Definition: Unit.cpp:5520
float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const
Definition: Unit.cpp:15242
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
Definition: Unit.cpp:2967
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
Definition: Unit.cpp:11893
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:13030

References AddComboPointGain(), AddPct(), ApplyPct(), AURA_STATE_BLEEDING, AURA_STATE_DEADLY_POISON, BASE_ATTACK, Unit::CalculateDamage(), CalculateSpellDamage(), Unit::CastSpell(), DISPEL_POISON, EFFECT_0, EFFECT_1, EFFECT_2, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetAura(), Unit::GetAuraEffect(), Unit::GetAuraEffectDummy(), Unit::GetDiseasesByCaster(), Unit::GetDummyAuraEffect(), Object::GetEntry(), Object::GetGUID(), Unit::GetModifierValue(), Unit::GetOwner(), Unit::GetPower(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), Unit::HasAuraType(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), Unit::IsScriptOverriden(), ITEM_SUBCLASS_WEAPON_DAGGER, m_attackType, m_caster, m_damage, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::MeleeDamageBonusDone(), Unit::MeleeDamageBonusTaken(), OFF_ATTACK, POWER_RUNIC_POWER, RANGED_ATTACK, roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_DUMMY, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, Unit::SpellBaseDamageBonusDone(), SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, Object::ToPlayer(), TOTAL_PCT, UNIT_MOD_DAMAGE_MAINHAND, UNIT_MOD_DAMAGE_OFFHAND, UNIT_MOD_DAMAGE_RANGED, and unitTarget.

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5144{
5145 InitEffectExecuteData(effIndex);
5146 *m_effectExecuteData[effIndex] << uint32(entry);
5147}
void InitEffectExecuteData(uint8 effIndex)
Definition: Spell.cpp:8472

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5150{
5151 InitEffectExecuteData(effIndex);
5152 *m_effectExecuteData[effIndex] << uint32(entry);
5153}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5130{
5131 InitEffectExecuteData(effIndex);
5132 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5133 *m_effectExecuteData[effIndex] << int32(itemId);
5134 *m_effectExecuteData[effIndex] << int32(slot);
5135}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5116{
5117 InitEffectExecuteData(effIndex);
5118 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5119 *m_effectExecuteData[effIndex] << uint32(attCount);
5120}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5123{
5124 InitEffectExecuteData(effIndex);
5125 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5126 *m_effectExecuteData[effIndex] << uint32(spellId);
5127}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5138{
5139 InitEffectExecuteData(effIndex);
5140 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5141}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5168{
5169 InitEffectExecuteData(effIndex);
5170 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5171}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ ExecuteLogEffectSummonObject()

◆ ExecuteLogEffectTakeTargetPower()

void Spell::ExecuteLogEffectTakeTargetPower ( uint8  effIndex,
Unit target,
uint32  PowerType,
uint32  powerTaken,
float  gainMultiplier 
)
5107{
5108 InitEffectExecuteData(effIndex);
5109 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5110 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5111 *m_effectExecuteData[effIndex] << uint32(PowerType);
5112 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5113}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectPowerBurn(), EffectPowerDrain(), and spell_mage_burnout_trigger::HandleDummy().

◆ ExecuteLogEffectUnsummonObject()

void Spell::ExecuteLogEffectUnsummonObject ( uint8  effIndex,
WorldObject obj 
)
5162{
5163 InitEffectExecuteData(effIndex);
5164 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5165}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4482{
4483 if (!m_caster)
4484 return;
4485
4487 return;
4489
4490 if (m_spellInfo->IsChanneled())
4492
4495
4496 // Unsummon summon as possessed creatures on spell cancel
4498 {
4499 if (Unit* charm = m_caster->GetCharm())
4500 if (charm->IsCreature()
4501 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4502 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4503 ((Puppet*)charm)->UnSummon();
4504 }
4505
4506 if (Creature* creatureCaster = m_caster->ToCreature())
4507 creatureCaster->ReleaseFocus(this);
4508
4509 if (ok)
4510 {
4513 }
4514 else
4515 {
4516 if (m_caster->IsPlayer())
4517 {
4518 // Xinef: Restore spell mods in case of fail cast
4520
4521 // Xinef: Reset cooldown event in case of fail cast
4524 }
4525 return;
4526 }
4527
4528 // pussywizard:
4531
4533 {
4534 // Unsummon statue
4536 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4537 if (spellInfo && spellInfo->SpellIconID == 2056)
4538 {
4539 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4540 m_caster->setDeathState(DeathState::JustDied);
4541 return;
4542 }
4543 }
4544
4545 // potions disabled by client, send event "not in combat" if need
4548
4549 // Take mods after trigger spell (needed for 14177 to affect 48664)
4550 // mods are taken only on succesfull cast and independantly from targets of the spell
4551 if (Player* player = m_caster->GetSpellModOwner())
4552 player->RemoveSpellMods(this);
4553
4554 // xinef: clear reactive auras states after spell cast
4557
4558 // Stop Attack for some spells
4561}
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition: Map.h:309
@ UNIT_MASK_PUPPET
Definition: UnitDefines.h:141
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition: SpellInfo.h:207
@ AURA_STATE_DEFENSE
Definition: SharedDefines.h:1292
@ AURA_STATE_HUNTER_PARRY
Definition: SharedDefines.h:1298
Definition: TemporarySummon.h:114
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition: PlayerUpdates.cpp:1497
virtual void setDeathState(DeathState s, bool despawn=false)
Definition: Unit.cpp:14506
void UpdateInterruptMask()
Definition: Unit.cpp:754
void ModifyAuraState(AuraStateType flag, bool apply)
Definition: Unit.cpp:10458
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition: Map.cpp:3471

References Unit::AttackStop(), AURA_STATE_DEFENSE, AURA_STATE_HUNTER_PARRY, SpellInfo::CasterAuraState, Unit::ClearUnitState(), ENCOUNTER_CREDIT_CAST_SPELL, WorldObject::FindMap(), Unit::GetCharm(), Object::GetGUID(), Unit::GetSpellModOwner(), Object::GetUInt32Value(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsSummon(), LOG_DEBUG, m_caster, m_spellInfo, m_spellState, m_triggeredByAuraSpell, Unit::ModifyAuraState(), Player::RemoveSpellCooldown(), Player::RestoreSpellMods(), Player::SendCooldownEvent(), Unit::setDeathState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_ENCOUNTER_REWARD, SPELL_STATE_FINISHED, SpellInfo::SpellIconID, sSpellMgr, Object::ToCreature(), Object::ToPlayer(), ObjectGuid::ToString(), UNIT_CREATED_BY_SPELL, UNIT_MASK_PUPPET, UNIT_STATE_CASTING, Map::UpdateEncounterState(), Unit::UpdateInterruptMask(), and Player::UpdatePotionCooldown().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), EffectInstaKill(), EffectTameCreature(), EffectTriggerRitualOfSummoning(), SpellScript::FinishCast(), Unit::FinishSpell(), handle_delayed(), handle_immediate(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and update().

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8468{
8470}
void SendLogExecute()
Definition: Spell.cpp:5072

References SendLogExecute().

Referenced by handle_delayed(), handle_immediate(), and HandleLaunchPhase().

◆ GetCaster()

Unit * Spell::GetCaster ( ) const
inline

◆ GetCastTime()

int32 Spell::GetCastTime ( ) const
inline
547{ return m_casttime; }

References m_casttime.

Referenced by Unit::InterruptSpell(), and Unit::SetCurrentCastedSpell().

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

std::string Spell::GetDebugInfo ( ) const
protected
8931{
8932 std::stringstream sstr;
8933 sstr << std::boolalpha
8934 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8935 << " State: " << getState();
8936 return sstr.str();
8937}

References GetSpellInfo(), getState(), SpellInfo::Id, m_originalCasterGUID, and ObjectGuid::ToString().

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

uint64 Spell::GetDelayStart ( ) const
inline
562{ return m_delayStart; }

References m_delayStart.

Referenced by SpellEvent::Execute(), and RecalculateDelayMomentForDst().

◆ GetDelayTrajectory()

uint64 Spell::GetDelayTrajectory ( ) const
inline
565{ return m_delayTrajectory; }

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

int32 Spell::GetPowerCost ( ) const
inline
576{ return m_powerCost; }

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2111{
2112 // this function selects which containers need to be searched for spell target
2114
2115 // filter searchers based on searched object type
2116 switch (objType)
2117 {
2124 break;
2128 break;
2129 default:
2130 break;
2131 }
2133 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2137 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2138
2139 if (condList)
2140 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2141 return retMask;
2142}
@ GRID_MAP_TYPE_MASK_PLAYER
Definition: GridDefines.h:73
@ GRID_MAP_TYPE_MASK_CREATURE
Definition: GridDefines.h:70
@ GRID_MAP_TYPE_MASK_ALL
Definition: GridDefines.h:74
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition: GridDefines.h:72
@ GRID_MAP_TYPE_MASK_CORPSE
Definition: GridDefines.h:69
@ TARGET_OBJECT_TYPE_CORPSE
Definition: SpellInfo.h:106
@ TARGET_OBJECT_TYPE_GOBJ
Definition: SpellInfo.h:103
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition: SpellInfo.h:109
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition: SpellInfo.h:108
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition: SpellInfo.h:104
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition: SharedDefines.h:456
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition: SharedDefines.h:505
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition: SharedDefines.h:501

References GRID_MAP_TYPE_MASK_ALL, GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, SpellInfo::HasAttribute(), m_spellInfo, sConditionMgr, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR3_ONLY_ON_GHOSTS, SPELL_ATTR3_ONLY_ON_PLAYER, TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE_ALLY, TARGET_OBJECT_TYPE_CORPSE_ENEMY, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_UNIT, and TARGET_OBJECT_TYPE_UNIT_AND_DEST.

Referenced by SearchAreaTargets(), SearchNearbyTarget(), and SelectImplicitConeTargets().

◆ GetSpellInfo()

◆ GetSpellSchoolMask()

SpellSchoolMask Spell::GetSpellSchoolMask ( ) const
inline

◆ GetSpellValue()

SpellValue const * Spell::GetSpellValue ( )
inline
583{ return m_spellValue; }

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

TriggerCastFlags Spell::GetTriggeredCastFlags ( ) const
inline
591{ return _triggeredCastFlags; }

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4175{
4176 if (!UpdatePointers())
4177 {
4178 // finish the spell if UpdatePointers() returned false, something wrong happened there
4179 finish(false);
4180 return 0;
4181 }
4182
4183 Player* modOwner = m_caster->GetSpellModOwner();
4184 if (modOwner)
4185 modOwner->SetSpellModTakingSpell(this, true);
4186
4187 uint64 next_time = m_delayTrajectory;
4188
4190
4191 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4192 {
4194 m_immediateHandled = true;
4196 next_time = 0;
4197 }
4198
4199 bool single_missile = (m_targets.HasDst());
4200
4201 // now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
4202 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4203 {
4204 if (ihit->processed == false)
4205 {
4206 if (single_missile || ihit->timeDelay <= t_offset)
4207 {
4208 ihit->timeDelay = t_offset;
4209 DoAllEffectOnTarget(&(*ihit));
4210 }
4211 else if (next_time == 0 || ihit->timeDelay < next_time)
4212 next_time = ihit->timeDelay;
4213 }
4214 }
4215
4216 // now recheck gameobject targeting correctness
4217 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4218 {
4219 if (ighit->processed == false)
4220 {
4221 if (single_missile || ighit->timeDelay <= t_offset)
4222 DoAllEffectOnTarget(&(*ighit));
4223 else if (next_time == 0 || ighit->timeDelay < next_time)
4224 next_time = ighit->timeDelay;
4225 }
4226 }
4227
4229
4230 if (modOwner)
4231 modOwner->SetSpellModTakingSpell(this, false);
4232
4233 // All targets passed - need finish phase
4234 if (next_time == 0)
4235 {
4236 // spell is finished, perform some last features of the spell here
4238
4239 finish(true); // successfully finish spell cast
4240
4241 // return zero, spell is finished now
4242 return 0;
4243 }
4244 else
4245 {
4246 // spell is unfinished, return next execution time
4247 return next_time;
4248 }
4249}
void _handle_finish_phase()
Definition: Spell.cpp:4279
void PrepareTargetProcessing()
Definition: Spell.cpp:8462
void _handle_immediate_phase()
Definition: Spell.cpp:4251
void FinishTargetProcessing()
Definition: Spell.cpp:8467

References _handle_finish_phase(), _handle_immediate_phase(), DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), Unit::GetSpellModOwner(), SpellCastTargets::HasDst(), m_caster, m_delayTrajectory, m_immediateHandled, m_targets, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), Player::SetSpellModTakingSpell(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ handle_immediate()

void Spell::handle_immediate ( )
4115{
4116 // start channeling if applicable
4117 if (m_spellInfo->IsChanneled())
4118 {
4119 int32 duration = m_spellInfo->GetDuration();
4121 duration = -1;
4122
4123 if (duration > 0)
4124 {
4125 // First mod_duration then haste - see Missile Barrage
4126 // Apply duration mod
4127 if (Player* modOwner = m_caster->GetSpellModOwner())
4128 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4129
4130 // Apply haste mods
4132 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4133
4136 m_channeledDuration = duration;
4137 SendChannelStart(duration);
4138 }
4139 else if (duration == -1)
4140 {
4143 SendChannelStart(duration);
4144 }
4145 }
4146
4148
4149 // process immediate effects (items, ground, etc.) also initialize some variables
4151
4152 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4153 DoAllEffectOnTarget(&(*ihit));
4154
4155 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4156 DoAllEffectOnTarget(&(*ihit));
4157
4159
4160 // spell is finished, perform some last features of the spell here
4162
4163 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4164 TakeCastItem();
4165
4166 // handle ammo consumption for Hunter's volley spell
4168 TakeAmmo();
4169
4171 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4172}
void AddInterruptMask(uint32 mask)
Definition: Unit.h:1516
void SendChannelStart(uint32 duration)
Definition: Spell.cpp:5205
void TakeAmmo()
Definition: Spell.cpp:5378

References _handle_finish_phase(), _handle_immediate_phase(), Unit::AddInterruptMask(), SpellInfo::ChannelInterruptFlags, DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), SpellInfo::GetDuration(), Object::GetFloatValue(), Unit::GetSpellModOwner(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsRangedWeaponSpell(), m_caster, m_channeledDuration, m_spellInfo, m_spellState, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), SendChannelStart(), SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_PERIODIC_HASTE, SPELL_STATE_CASTING, SPELLMOD_DURATION, TakeAmmo(), TakeCastItem(), TRIGGERED_IGNORE_EFFECTS, and UNIT_MOD_CAST_SPEED.

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5627{
5629 return;
5630
5631 effectHandleMode = mode;
5632 unitTarget = pUnitTarget;
5633 itemTarget = pItemTarget;
5634 gameObjTarget = pGOTarget;
5636
5637 uint8 eff = m_spellInfo->Effects[i].Effect;
5638
5639 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5640
5641 // we do not need DamageMultiplier here.
5642 damage = CalculateSpellDamage(i, nullptr);
5643
5644 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5645
5646 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5647 {
5648 (this->*SpellEffects[eff])((SpellEffIndex)i);
5649 }
5650}
SpellEffIndex
Definition: SharedDefines.h:30
SpellEffects
Definition: SharedDefines.h:778
@ TOTAL_SPELL_EFFECTS
Definition: SharedDefines.h:943
WorldLocation _position
Definition: Spell.h:103
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition: Spell.cpp:8581

References SpellDestination::_position, CalculateSpellDamage(), CallScriptEffectHandlers(), damage, destTarget, effectHandleMode, SpellInfo::Effects, gameObjTarget, HasTriggeredCastFlag(), SpellInfo::Id, itemTarget, LOG_DEBUG, m_destTargets, m_spellInfo, TOTAL_SPELL_EFFECTS, TRIGGERED_IGNORE_EFFECTS, and unitTarget.

Referenced by _handle_immediate_phase(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), and HandleLaunchPhase().

◆ HandleLaunchPhase()

void Spell::HandleLaunchPhase ( )
protected
8231{
8232 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8233 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8234 {
8235 // don't do anything for empty effect
8236 if (!m_spellInfo->Effects[i].IsEffect())
8237 continue;
8238
8239 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8240 }
8241
8242 float multiplier[MAX_SPELL_EFFECTS];
8243 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8244 if (m_applyMultiplierMask & (1 << i))
8245 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8246
8249 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8250 {
8251 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8252 usesAmmo = false;
8253 }
8254
8256
8257 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8258 {
8259 TargetInfo& target = *ihit;
8260
8261 uint32 mask = target.effectMask;
8262 if (!mask)
8263 continue;
8264
8265 // do not consume ammo anymore for Hunter's volley spell
8267 usesAmmo = false;
8268
8269 if (usesAmmo)
8270 {
8271 bool ammoTaken = false;
8272 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8273 {
8274 if (!(mask & 1 << i))
8275 continue;
8276 switch (m_spellInfo->Effects[i].Effect)
8277 {
8283 ammoTaken = true;
8284 TakeAmmo();
8285 }
8286 if (ammoTaken)
8287 break;
8288 }
8289 }
8290
8291 DoAllEffectOnLaunchTarget(target, multiplier);
8292 }
8293
8295}
@ SPELL_AURA_ABILITY_CONSUME_NO_AMMO
Definition: SpellAuraDefines.h:337
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition: SpellInfo.h:184
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition: SharedDefines.h:780
void DoAllEffectOnLaunchTarget(TargetInfo &targetInfo, float *multiplier)
Definition: Spell.cpp:8297

References DoAllEffectOnLaunchTarget(), TargetInfo::effectMask, SpellInfo::Effects, FinishTargetProcessing(), Unit::GetAuraEffectsByType(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::IsTargetingArea(), IsTriggered(), m_applyMultiplierMask, m_caster, m_originalCaster, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, PrepareTargetProcessing(), SPELL_ATTR0_CU_DIRECT_DAMAGE, SPELL_AURA_ABILITY_CONSUME_NO_AMMO, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, and TakeAmmo().

Referenced by _cast().

◆ HandleThreatSpells()

void Spell::HandleThreatSpells ( )
5580{
5581 if (m_UniqueTargetInfo.empty())
5582 return;
5583
5585 return;
5586
5587 float threat = 0.0f;
5588 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5589 {
5590 if (threatEntry->apPctMod != 0.0f)
5591 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5592
5593 threat += threatEntry->flatMod;
5594 }
5596 threat += m_spellInfo->SpellLevel;
5597
5598 // past this point only multiplicative effects occur
5599 if (threat == 0.0f)
5600 return;
5601
5602 // since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
5603 threat /= m_UniqueTargetInfo.size();
5604
5605 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5606 {
5607 float threatToAdd = threat;
5608 if (ihit->missCondition != SPELL_MISS_NONE)
5609 threatToAdd = 0.0f;
5610
5611 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5612 if (!target)
5613 continue;
5614
5615 bool IsFriendly = m_caster->IsFriendlyTo(target);
5616 // positive spells distribute threat among all units that are in combat with target, like healing
5618 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5619 // for negative spells threat gets distributed among affected targets
5620 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5621 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5622 }
5623 LOG_DEBUG("spells.aura", "Spell {}, added an additional {} threat for {} {} target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
5624}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition: SpellInfo.h:180
static bool IsFriendly(Creature *piece, Creature *target)
Definition: boss_chess_event.cpp:178
bool _IsPositiveSpell() const
Definition: SpellInfo.cpp:2839
Definition: SpellMgr.h:385

References SpellInfo::_IsPositiveSpell(), Unit::AddThreat(), BASE_ATTACK, Unit::CanHaveThreatList(), Unit::getHostileRefMgr(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, IsFriendly(), Unit::IsFriendlyTo(), LOG_DEBUG, m_caster, m_spellInfo, m_UniqueTargetInfo, SPELL_ATTR0_CU_NO_INITIAL_THREAT, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_MISS_NONE, SpellInfo::SpellLevel, sSpellMgr, and HostileRefMgr::threatAssist().

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected

◆ HasTriggeredCastFlag()

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8101{
8102 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8103 if (itr->effectMask & (1 << effect))
8104 return true;
8105
8106 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8107 if (itr->effectMask & (1 << effect))
8108 return true;
8109
8110 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8111 if (itr->effectMask & (1 << effect))
8112 return true;
8113
8114 return false;
8115}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8473{
8474 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8475 if (!m_effectExecuteData[effIndex])
8476 {
8477 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8478 // first dword - target counter
8479 *m_effectExecuteData[effIndex] << uint32(1);
8480 }
8481 else
8482 {
8483 // increase target counter by one
8484 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8485 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8486 }
8487}

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by ExecuteLogEffectCreateItem(), ExecuteLogEffectDestroyItem(), ExecuteLogEffectDurabilityDamage(), ExecuteLogEffectExtraAttacks(), ExecuteLogEffectInterruptCast(), ExecuteLogEffectOpenLock(), ExecuteLogEffectResurrect(), ExecuteLogEffectSummonObject(), ExecuteLogEffectTakeTargetPower(), and ExecuteLogEffectUnsummonObject().

◆ InitExplicitTargets()

void Spell::InitExplicitTargets ( SpellCastTargets const &  targets)
715{
716 m_targets = targets;
717 // this function tries to correct spell explicit targets for spell
718 // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside
719 // this also makes sure that we correctly send explicit targets to client (removes redundant data)
720 uint32 neededTargets = m_spellInfo->GetExplicitTargetMask();
721
722 if (WorldObject* target = m_targets.GetObjectTarget())
723 {
724 // check if object target is valid with needed target flags
725 // for unit case allow corpse target mask because player with not released corpse is a unit target
726 if ((target->ToUnit() && !(neededTargets & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)))
727 || (target->ToGameObject() && !(neededTargets & TARGET_FLAG_GAMEOBJECT_MASK))
728 || (target->ToCorpse() && !(neededTargets & TARGET_FLAG_CORPSE_MASK)))
730 }
731 else
732 {
733 // try to select correct unit target if not provided by client or by serverside cast
734 if (neededTargets & (TARGET_FLAG_UNIT_MASK))
735 {
736 Unit* unit = nullptr;
737 // try to use player selection as a target
738 if (Player* playerCaster = m_caster->ToPlayer())
739 {
740 // selection has to be found and to be valid target for the spell
741 if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
743 unit = selectedUnit;
744 }
745 // try to use attacked unit as a target
746 else if ((m_caster->IsCreature()) && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT))
747 unit = m_caster->GetVictim();
748
749 // didn't find anything - let's use self as target
750 if (!unit && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY))
751 unit = m_caster;
752
754 }
755 }
756
757 // check if spell needs dst target
758 if (neededTargets & TARGET_FLAG_DEST_LOCATION)
759 {
760 // and target isn't set
761 if (!m_targets.HasDst())
762 {
763 // try to use unit target if provided
764 if (WorldObject* target = targets.GetObjectTarget())
765 m_targets.SetDst(*target);
766 // or use self if not available
767 else
769 }
770 }
771 else
773
774 if (neededTargets & TARGET_FLAG_SOURCE_LOCATION)
775 {
776 if (!targets.HasSrc())
778 }
779 else
781}
@ TARGET_FLAG_UNIT_RAID
Definition: SpellInfo.h:48
@ TARGET_FLAG_UNIT_ALLY
Definition: SpellInfo.h:54
@ TARGET_FLAG_SOURCE_LOCATION
Definition: SpellInfo.h:51
@ TARGET_FLAG_CORPSE_MASK
Definition: SpellInfo.h:71
@ TARGET_FLAG_UNIT_PARTY
Definition: SpellInfo.h:49
void RemoveObjectTarget()
Definition: Spell.cpp:322
void RemoveDst()
Definition: Spell.cpp:449
void RemoveSrc()
Definition: Spell.cpp:392

References SpellInfo::CheckExplicitTarget(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetObjectTarget(), Unit::GetTarget(), ObjectAccessor::GetUnit(), Unit::GetVictim(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), Object::IsCreature(), m_caster, m_spellInfo, m_targets, SpellCastTargets::RemoveDst(), SpellCastTargets::RemoveObjectTarget(), SpellCastTargets::RemoveSrc(), SpellCastTargets::SetDst(), SpellCastTargets::SetSrc(), SpellCastTargets::SetUnitTarget(), SPELL_CAST_OK, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_SOURCE_LOCATION, TARGET_FLAG_UNIT, TARGET_FLAG_UNIT_ALLY, TARGET_FLAG_UNIT_ENEMY, TARGET_FLAG_UNIT_MASK, TARGET_FLAG_UNIT_PARTY, TARGET_FLAG_UNIT_RAID, and Object::ToPlayer().

Referenced by Player::CastItemUseSpell(), and prepare().

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8075{
8078 {
8079 return false;
8080 }
8081
8083 {
8084 return false;
8085 }
8086
8087 return true;
8088}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition: SharedDefines.h:629

References SpellInfo::HasAttribute(), SpellInfo::InterruptFlags, IsTriggered(), m_casttime, m_spellInfo, SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT, and SPELL_INTERRUPT_FLAG_INTERRUPT.

Referenced by _cast().

◆ IsAutoRepeat()

bool Spell::IsAutoRepeat ( ) const
inline

◆ IsChannelActive()

bool Spell::IsChannelActive ( ) const
inline
@ UNIT_CHANNEL_SPELL
Definition: UpdateFields.h:94

References Object::GetUInt32Value(), m_caster, and UNIT_CHANNEL_SPELL.

Referenced by Creature::IsMovementPreventedByCasting().

◆ isDelayableNoMore()

bool Spell::isDelayableNoMore ( )
inlineprotected
629 {
630 if (m_delayAtDamageCount >= 2)
631 return true;
632
634 return false;
635 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
560{ return !m_executedCurrently; }

References m_executedCurrently.

Referenced by Unit::InterruptSpell().

◆ IsNeedSendToClient()

◆ IsNextMeleeSwingSpell()

bool Spell::IsNextMeleeSwingSpell ( ) const

◆ IsTriggered()

◆ IsValidDeadOrAliveTarget()

bool Spell::IsValidDeadOrAliveTarget ( Unit const *  target) const
protected
8223{
8224 if (target->IsAlive())
8226
8228}
bool IsRequiringDeadTarget() const
Definition: SpellInfo.cpp:1221
bool IsAllowingDeadTarget() const
Definition: SpellInfo.cpp:1226

References Unit::IsAlive(), SpellInfo::IsAllowingDeadTarget(), SpellInfo::IsRequiringDeadTarget(), and m_spellInfo.

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8496{
8497 if (_scriptsLoaded)
8498 return;
8499 _scriptsLoaded = true;
8500 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8501 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8502 {
8503 if (!(*itr)->_Load(this))
8504 {
8505 std::list<SpellScript*>::iterator bitr = itr;
8506 ++itr;
8507 delete (*bitr);
8508 m_loadedScripts.erase(bitr);
8509 continue;
8510 }
8511 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8512 (*itr)->Register();
8513 ++itr;
8514 }
8515}

References _scriptsLoaded, SpellInfo::Id, LOG_DEBUG, m_loadedScripts, m_spellInfo, and sScriptMgr.

Referenced by WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), and PetAI::UpdateAI().

◆ OnSpellLaunch()

void Spell::OnSpellLaunch ( )
8901{
8902 if (!m_caster || !m_caster->IsInWorld())
8903 return;
8904
8905 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8906
8907 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8908 // can succeed with a lockId of 0
8909 if (m_spellInfo->Id == 21651)
8910 {
8911 if (GameObject* go = m_targets.GetGOTarget())
8912 {
8913 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8914 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8915 {
8916 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8917 visual->prepare(&m_targets);
8918 }
8919 }
8920 }
8921}
@ TRIGGERED_NONE
Definition: SpellDefines.h:131
@ LOCKTYPE_SLOW_OPEN
Definition: SharedDefines.h:2608

References SpellCastTargets::GetGOTarget(), SpellInfo::Id, LockEntry::Index, Object::IsInWorld(), LOCKTYPE_SLOW_OPEN, m_caster, m_spellInfo, m_targets, prepare(), sLockStore, sSpellMgr, and TRIGGERED_NONE.

Referenced by prepare().

◆ prepare()

SpellCastResult Spell::prepare ( SpellCastTargets const *  targets,
AuraEffect const *  triggeredByAura = nullptr 
)

m_castItemGUID &&

3477{
3478 if (m_CastItem)
3479 {
3481 }
3482 else
3483 {
3485 }
3486
3487 InitExplicitTargets(*targets);
3488
3489 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3490 {
3491 finish(false);
3492 return SPELL_FAILED_UNKNOWN;
3493 }
3494
3495 // Fill aura scaling information
3497 {
3498 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3499 {
3500 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3503 {
3504 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3506 {
3507 m_auraScaleMask |= (1 << i);
3508 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3509 {
3510 m_auraScaleMask = 0;
3511 break;
3512 }
3513 }
3514 }
3515 }
3516 }
3517
3519
3520 if (triggeredByAura)
3521 {
3522 m_triggeredByAuraSpell.Init(triggeredByAura);
3523 }
3524
3525 // create and add update event for this spell
3526 _spellEvent = new SpellEvent(this);
3528
3530 {
3532 finish(false);
3534 }
3535
3536 //Prevent casting at cast another spell (ServerSide check)
3538 {
3540 finish(false);
3542 }
3543
3544 LoadScripts();
3545
3546 OnSpellLaunch();
3547
3549
3550 // Set combo point requirement
3552 m_needComboPoints = false;
3553
3554 SpellCastResult result = CheckCast(true);
3555 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3556 {
3557 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3558 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3559 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3560 // a possible alternative sollution for those would be validating aura target on unit state change
3561 if (m_caster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3562 {
3564 triggeredByAura->GetBase()->SetDuration(0);
3565 }
3566
3567 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3569 {
3570 SendCastResult(result);
3571
3572 finish(false);
3573 return result;
3574 }
3575 }
3576
3577 // Prepare data for triggers
3578 prepareDataForTriggerSystem(triggeredByAura);
3579
3580 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3582
3583 if (m_caster->IsPlayer())
3585 m_casttime = 0;
3586
3587 // don't allow channeled spells / spells with cast time to be casted while moving
3588 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3590 {
3591 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3593 {
3595 finish(false);
3596 return SPELL_FAILED_MOVING;
3597 }
3598 }
3599
3600 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3601 if (m_CastItem)
3602 {
3603 bool selectTargets = false;
3604 bool nearbyDest = false;
3605
3606 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3607 {
3608 if (!m_spellInfo->Effects[i].IsEffect())
3609 continue;
3610
3611 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3612 {
3613 selectTargets = false;
3614 break;
3615 }
3616
3617 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3618 {
3619 nearbyDest = true;
3620 }
3621
3622 // xinef: by default set it to false, and to true if any valid target is found
3623 selectTargets = true;
3624 }
3625
3626 if (selectTargets)
3627 {
3629 _spellTargetsSelected = true;
3630 bool spellFailed = false;
3631
3632 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3633 {
3634 // no valid nearby target unit or game object found; check if nearby destination type
3635 if (nearbyDest)
3636 {
3637 if (!m_targets.HasDst())
3638 {
3639 // no valid target destination
3640 spellFailed = true;
3641 }
3642 }
3643 else
3644 {
3645 spellFailed = true;
3646 }
3647 }
3648
3649 if (spellFailed)
3650 {
3652 finish(false);
3654 }
3655 }
3656 }
3657
3658 // set timer base at cast time
3659 ReSetTimer();
3660
3661 LOG_DEBUG("spells.aura", "Spell::prepare: spell id {} source {} caster {} customCastFlags {} mask {}", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, _triggeredCastFlags, m_targets.GetTargetMask());
3662
3664 {
3666 }
3667
3668 //Containers for channeled spells have to be set
3669 //TODO:Apply this to all casted spells if needed
3670 // Why check duration? 29350: channelled triggers channelled
3672 cast(true);
3673 else
3674 {
3675 // stealth must be removed at cast starting (at show channel bar)
3676 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3678 {
3679 // Farsight spells exception
3680 uint32 exceptSpellId = 0;
3682 {
3683 exceptSpellId = m_spellInfo->Id;
3684 }
3685
3688 }
3689
3692
3693 // set target for proper facing
3695 {
3698 {
3699 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3700 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3702 }
3703 }
3704
3705 //item: first cast may destroy item and second cast causes crash
3706 // xinef: removed !m_spellInfo->StartRecoveryTime
3707 // second los check failed in events
3708 // xinef: removed itemguid check, currently there is no such item in database
3710 cast(true);
3711
3714 }
3715
3716 return SPELL_CAST_OK;
3717}
@ CHEAT_CASTTIME
Definition: Player.h:1000
@ AURA_INTERRUPT_FLAG_SPELL_ATTACK
Definition: SpellDefines.h:57
@ AURA_INTERRUPT_FLAG_CAST
Definition: SpellDefines.h:46
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition: SpellDefines.h:136
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition: SpellDefines.h:140
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition: SpellDefines.h:138
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition: SpellDefines.h:27
@ TARGET_SELECT_CATEGORY_NEARBY
Definition: SpellInfo.h:80
@ TARGET_OBJECT_TYPE_DEST
Definition: SpellInfo.h:100
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition: SharedDefines.h:813
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition: SharedDefines.h:843
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition: SharedDefines.h:409
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition: Creature.cpp:3550
void SetCurrentCastedSpell(Spell *pSpell)
Definition: Unit.cpp:3940
bool IsSitState() const
Definition: Unit.cpp:16666
Definition: Spell.cpp:520
void Init(AuraEffect const *aurEff)
Definition: Spell.cpp:8923
void LoadScripts()
Definition: Spell.cpp:8495
void cast(bool skipCheck=false)
Definition: Spell.cpp:3790
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition: Spell.cpp:2292
void SendSpellStart()
Definition: Spell.cpp:4716
void TriggerGlobalCooldown()
Definition: Spell.cpp:8839
void OnSpellLaunch()
Definition: Spell.cpp:8900
CurrentSpellTypes GetCurrentContainer() const
Definition: Spell.cpp:7910
void ReSetTimer()
Definition: Spell.h:550
void InitExplicitTargets(SpellCastTargets const &targets)
Definition: Spell.cpp:714
bool IsActionAllowedChannel() const
Definition: SpellInfo.cpp:1260
int32 GetMaxDuration() const
Definition: SpellInfo.cpp:2344
uint32 Attributes
Definition: SpellInfo.h:324
bool IsBreakingStealth() const
Definition: SpellInfo.cpp:1270

References _spellEvent, _spellTargetsSelected, _triggeredCastFlags, EventProcessor::AddEvent(), SpellInfo::Attributes, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_NOT_SEATED, AURA_INTERRUPT_FLAG_SPELL_ATTACK, SpellInfo::AuraInterruptFlags, SpellInfo::CalcCastTime(), SpellInfo::CalcPowerCost(), EventProcessor::CalculateTime(), cast(), CHEAT_CASTTIME, CheckCast(), CURRENT_GENERIC_SPELL, DISABLE_TYPE_SPELL, EFFECT_0, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, finish(), Creature::FocusTarget(), AuraEffect::GetBase(), Player::GetCommandStatus(), GetCurrentContainer(), Object::GetEntry(), Object::GetGUID(), SpellInfo::GetMaxDuration(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetTargetMask(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasTriggeredCastFlag(), SpellInfo::Id, TriggeredByAuraSpellData::Init(), InitExplicitTargets(), SpellInfo::InterruptFlags, SpellInfo::IsActionAllowedChannel(), IsAutoRepeat(), SpellInfo::IsBreakingStealth(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), DisableMgr::IsDisabledFor(), Creature::IsInEvadeMode(), Unit::isMoving(), IsNextMeleeSwingSpell(), Unit::IsNonMeleeSpellCast(), Aura::IsPassive(), SpellInfo::IsPassive(), AuraEffect::IsPeriodic(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsSitState(), Unit::IsTotem(), IsTriggered(), LoadScripts(), LOG_DEBUG, m_auraScaleMask, m_cast_count, m_caster, m_CastItem, m_castItemGUID, m_casttime, Unit::m_Events, m_needComboPoints, m_originalCaster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_spellState, m_spellValue, m_targets, m_triggeredByAuraSpell, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, OnSpellLaunch(), prepareDataForTriggerSystem(), Unit::RemoveAurasWithInterruptFlags(), ReSetTimer(), SelectSpellTargets(), SendCastResult(), SendChannelUpdate(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Aura::SetDuration(), Unit::SetStandState(), SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_CAST_OK, SPELL_EFFECT_ADD_FARSIGHT, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AREA_AURA_RAID, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_MOVING, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_UNKNOWN, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_PREPARING, SpellInfo::SpellLevel, sScriptMgr, TARGET_CHECK_ENTRY, TARGET_OBJECT_TYPE_DEST, TARGET_SELECT_CATEGORY_NEARBY, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS, TRIGGERED_IGNORE_AURA_SCALING, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TRIGGERED_IGNORE_COMBO_POINTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_SET_FACING, TriggerGlobalCooldown(), and UNIT_STAND_STATE_STAND.

Referenced by Unit::_UpdateAutoRepeatSpell(), Player::CastItemUseSpell(), Unit::CastSpell(), EffectEnchantItemTmp(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), OnSpellLaunch(), and PetAI::UpdateAI().

◆ prepareDataForTriggerSystem()

void Spell::prepareDataForTriggerSystem ( AuraEffect const *  triggeredByAura)
protected
2293{
2294 //==========================================================================================
2295 // Now fill data for trigger system, need know:
2296 // can spell trigger another or not (m_canTrigger)
2297 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2298 //==========================================================================================
2299
2301 // Get data for type of attack and fill base info for trigger
2302 switch (m_spellInfo->DmgClass)
2303 {
2306 if (m_attackType == OFF_ATTACK)
2308 else
2311 break;
2313 // Auto attack
2315 {
2318 }
2319 else // Ranged spell attack
2320 {
2323 }
2324 break;
2325 default:
2328 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2329 {
2332 }
2333 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2334 // Because spell positivity is dependant on target
2335 }
2337
2338 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2340 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2341 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2342 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2343 {
2345 }
2346
2347 /* Effects which are result of aura proc from triggered spell cannot proc
2348 to prevent chain proc of these spells */
2349
2350 // Hellfire Effect - trigger as DOT
2352 {
2355 }
2356
2357 // Ranged autorepeat attack is set as triggered spell - ignore it
2359 {
2366 }
2367 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2370}
@ TRIGGERED_DISALLOW_PROC_EVENTS
Will ignore caster aura restrictions or requirements.
Definition: SpellDefines.h:146
@ PROC_EX_NONE
Definition: SpellMgr.h:193
@ PROC_EX_INTERNAL_CANT_PROC
Definition: SpellMgr.h:218
@ PROC_EX_INTERNAL_TRIGGERED
Definition: SpellMgr.h:221
@ PROC_EX_INTERNAL_REQ_FAMILY
Definition: SpellMgr.h:222
@ PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:119
@ PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:117
@ PROC_FLAG_DONE_PERIODIC
Definition: SpellMgr.h:134
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:113
@ PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:120
@ PROC_FLAG_TAKEN_PERIODIC
Definition: SpellMgr.h:135
@ PROC_FLAG_DONE_MAINHAND_ATTACK
Definition: SpellMgr.h:140
@ PROC_FLAG_DONE_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:116
@ PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:114
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition: SpellMgr.h:138
@ PROC_FLAG_DONE_OFFHAND_ATTACK
Definition: SpellMgr.h:141
@ SPELL_ATTR2_ACTIVE_THREAT
Definition: SharedDefines.h:486
@ SPELL_ATTR3_NOT_A_PROC
Definition: SharedDefines.h:502

References SpellInfo::DmgClass, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, SpellInfo::HasAttribute(), HasTriggeredCastFlag(), SpellInfo::Id, Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsTotem(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellInfo, OFF_ATTACK, PROC_EX_INTERNAL_CANT_PROC, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_INTERNAL_TRIGGERED, PROC_EX_NONE, PROC_FLAG_DONE_MAINHAND_ATTACK, PROC_FLAG_DONE_OFFHAND_ATTACK, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_RANGED_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_TAKEN_PERIODIC, PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_ATTR2_ACTIVE_THREAT, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_NOT_A_PROC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLFAMILY_HUNTER, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Object::ToCreature(), and TRIGGERED_DISALLOW_PROC_EVENTS.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8576{
8577 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8578 (*scritr)->_InitHit();
8579}

References m_loadedScripts.

Referenced by _cast(), _handle_immediate_phase(), and DoAllEffectOnTarget().

◆ PrepareTargetProcessing()

void Spell::PrepareTargetProcessing ( )
protected

◆ PrepareTriggersExecutedOnHit()

void Spell::PrepareTriggersExecutedOnHit ( )
protected
Todo:
: move this to scripts
Todo:
: move this to scripts
8750{
8753 {
8754 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8755 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8757 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8758 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8760 }
8761
8764 {
8766 {
8767 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
8768 {
8770 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8771 {
8772 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8773 {
8774 m_preCastSpell = 26017;
8775 break;
8776 }
8777 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8778 m_preCastSpell = 67;
8779 }
8780 }
8781 break;
8782 }
8783 case SPELLFAMILY_DRUID:
8784 {
8785 // Faerie Fire (Feral)
8787 m_preCastSpell = 60089;
8788
8789 break;
8790 }
8791 }
8792
8793 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8794 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8795 // and to correctly calculate proc chance when combopoints are present
8797 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8798 {
8799 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8800 continue;
8801 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8802 uint32 auraSpellIdx = (*i)->GetEffIndex();
8803 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8804 {
8805 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8806 // this possibly needs fixing
8807 int32 auraBaseAmount = (*i)->GetBaseAmount();
8808 // proc chance is stored in effect amount
8809 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8810 // build trigger and add to the list
8811 HitTriggerSpell spellTriggerInfo;
8812 spellTriggerInfo.triggeredSpell = spellInfo;
8813 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8814 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8815 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8816 m_hitTriggerSpells.push_back(spellTriggerInfo);
8817 }
8818 }
8819}
@ FORM_DIREBEAR
Definition: UnitDefines.h:77
@ FORM_BEAR
Definition: UnitDefines.h:74
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:105
@ SPELL_AURA_ADD_TARGET_TRIGGER
Definition: SpellAuraDefines.h:172
uint32 ExcludeTargetAuraSpell
Definition: SpellInfo.h:346

References Unit::CalculateSpellDamage(), Spell::HitTriggerSpell::chance, EFFECT_0, SpellInfo::Effects, SpellInfo::ExcludeCasterAuraSpell, SpellInfo::ExcludeTargetAuraSpell, FORM_BEAR, FORM_DIREBEAR, Unit::GetAuraEffectsByType(), Unit::GetShapeshiftForm(), SpellInfo::Id, SpellInfo::IsPositive(), m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, SPELL_AURA_ADD_TARGET_TRIGGER, SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_DRUID, SPELLFAMILY_PALADIN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, sSpellMgr, Spell::HitTriggerSpell::triggeredByAura, Spell::HitTriggerSpell::triggeredByEffIdx, and Spell::HitTriggerSpell::triggeredSpell.

Referenced by _cast().

◆ RecalculateDelayMomentForDst()

void Spell::RecalculateDelayMomentForDst ( )
918{
921}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:27
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition: EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition: Spell.cpp:896
uint64 GetDelayStart() const
Definition: Spell.h:562

References _spellEvent, CalculateDelayMomentForDst(), GetDelayStart(), m_caster, m_delayMoment, Unit::m_Events, and EventProcessor::ModifyEventTime().

◆ ReSetTimer()

void Spell::ReSetTimer ( )
inline
550{ m_timer = m_casttime > 0 ? m_casttime : 0; }

References m_casttime, and m_timer.

Referenced by prepare().

◆ SearchAreaTargets()

void Spell::SearchAreaTargets ( std::list< WorldObject * > &  targets,
float  range,
Position const *  position,
Unit referer,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList 
)
2187{
2188 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2189 if (!containerTypeMask)
2190 return;
2191 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2192 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2193 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2194}
Definition: GridNotifiers.h:239
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition: Spell.cpp:2110

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SearchChainTargets(), and SelectImplicitAreaTargets().

◆ SearchChainTargets()

void Spell::SearchChainTargets ( std::list< WorldObject * > &  targets,
uint32  chainTargets,
WorldObject target,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectType,
SpellTargetSelectionCategories  selectCategory,
ConditionList condList,
bool  isChainHeal 
)
2197{
2198 // max dist for jump target selection
2199 float jumpRadius = 0.0f;
2200 switch (m_spellInfo->DmgClass)
2201 {
2203 // 7.5y for multi shot
2204 jumpRadius = 7.5f;
2205 break;
2207 // 5y for swipe, cleave and similar
2208 jumpRadius = 5.0f;
2209 break;
2212 // 12.5y for chain heal spell since 3.2 patch
2213 if (isChainHeal)
2214 jumpRadius = 12.5f;
2215 // 10y as default for magic chain spells
2216 else
2217 jumpRadius = 10.0f;
2218 break;
2219 }
2220
2221 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2225
2226 // max dist which spell can reach
2227 float searchRadius = jumpRadius;
2228 if (isBouncingFar)
2229 searchRadius *= chainTargets;
2230
2231 std::list<WorldObject*> tempTargets;
2232 SearchAreaTargets(tempTargets, searchRadius, target, m_caster, objectType, selectType, condList);
2233 tempTargets.remove(target);
2234
2235 // remove targets which are always invalid for chain spells
2236 // for some spells allow only chain targets in front of caster (swipe for example)
2237 if (!isBouncingFar)
2238 {
2239 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end();)
2240 {
2241 std::list<WorldObject*>::iterator checkItr = itr++;
2242 if (!m_caster->HasInArc(static_cast<float>(M_PI), *checkItr))
2243 tempTargets.erase(checkItr);
2244 }
2245 }
2246
2247 while (chainTargets)
2248 {
2249 // try to get unit for next chain jump
2250 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2251 // get unit with highest hp deficit in dist
2252 if (isChainHeal)
2253 {
2254 uint32 maxHPDeficit = 0;
2255 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2256 {
2257 if (Unit* unit = (*itr)->ToUnit())
2258 {
2259 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2260 if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2261 {
2262 foundItr = itr;
2263 maxHPDeficit = deficit;
2264 }
2265 }
2266 }
2267 }
2268 // get closest object
2269 else
2270 {
2271 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2272 {
2273 if (foundItr == tempTargets.end())
2274 {
2275 if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2276 foundItr = itr;
2277 }
2278 else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2279 foundItr = itr;
2280 }
2281 }
2282 // not found any valid target - chain ends
2283 if (foundItr == tempTargets.end())
2284 break;
2285 target = *foundItr;
2286 tempTargets.erase(foundItr);
2287 targets.push_back(target);
2288 --chainTargets;
2289 }
2290}
@ SPELL_ATTR4_BOUNCY_CHAIN_MISSILES
Definition: SharedDefines.h:548
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1316
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition: Object.cpp:1381
void SearchAreaTargets(std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
Definition: Spell.cpp:2186

References SpellInfo::DmgClass, WorldObject::GetDistanceOrder(), SpellInfo::HasAttribute(), Position::HasInArc(), WorldObject::IsWithinDist(), WorldObject::IsWithinLOSInMap(), VMAP::M2, m_caster, m_spellInfo, SearchAreaTargets(), SPELL_ATTR4_BOUNCY_CHAIN_MISSILES, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, and Object::ToUnit().

Referenced by SelectImplicitChainTargets().

◆ SearchNearbyTarget()

WorldObject * Spell::SearchNearbyTarget ( float  range,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList = nullptr 
)
2175{
2176 WorldObject* target = nullptr;
2177 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2178 if (!containerTypeMask)
2179 return nullptr;
2180 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2182 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2183 return target;
2184}
Definition: GridNotifiers.h:219

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SelectImplicitNearbyTargets().

◆ SearchTargets()

template<class SEARCHER >
void Spell::SearchTargets ( SEARCHER &  searcher,
uint32  containerMask,
Unit referer,
Position const *  pos,
float  radius 
)
2146{
2147 if (!containerMask)
2148 return;
2149
2150 // search world and grid for possible targets
2151 bool searchInGrid = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT);
2152 bool searchInWorld = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE);
2153
2154 if (searchInGrid || searchInWorld)
2155 {
2156 float x, y;
2157 x = pos->GetPositionX();
2158 y = pos->GetPositionY();
2159
2161 Cell cell(p);
2162 cell.SetNoCreate();
2163
2164 Map* map = referer->GetMap();
2165
2166 if (searchInWorld)
2167 Cell::VisitWorldObjects(x, y, map, searcher, radius);
2168
2169 if (searchInGrid)
2170 Cell::VisitGridObjects(x, y, map, searcher, radius);
2171 }
2172}
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:179

References Acore::ComputeCellCoord(), WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, Cell::SetNoCreate(), Cell::VisitGridObjects(), and Cell::VisitWorldObjects().

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
924{
925 if (!targetType.GetTarget())
926 return;
927
928 uint32 effectMask = 1 << effIndex;
929 // set the same target list for all effects
930 // some spells appear to need this, however this requires more research
931 switch (targetType.GetSelectionCategory())
932 {
936 {
937 // targets for effect already selected
938 if (effectMask & processedEffectMask)
939 {
940 return;
941 }
942
943 auto const& effects = GetSpellInfo()->Effects;
944
945 // choose which targets we can select at once
946 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
947 {
948 if (effects[j].IsEffect() &&
949 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
950 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
951 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
952 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
954 {
955 effectMask |= 1 << j;
956 }
957 }
958 processedEffectMask |= effectMask;
959 break;
960 }
961 default:
962 break;
963 }
964
965 switch (targetType.GetSelectionCategory())
966 {
968 SelectImplicitChannelTargets(effIndex, targetType);
969 break;
971 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
972 break;
974 SelectImplicitConeTargets(effIndex, targetType, effectMask);
975 break;
977 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
978 break;
980 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
981 CheckDst();
982
983 SelectImplicitTrajTargets(effIndex, targetType);
984 break;
986 switch (targetType.GetObjectType())
987 {
989 switch (targetType.GetReferenceType())
990 {
993 break;
994 default:
995 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
996 break;
997 }
998 break;
1000 switch (targetType.GetReferenceType())
1001 {
1003 SelectImplicitCasterDestTargets(effIndex, targetType);
1004 break;
1006 SelectImplicitTargetDestTargets(effIndex, targetType);
1007 break;
1009 SelectImplicitDestDestTargets(effIndex, targetType);
1010 break;
1011 default:
1012 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1013 break;
1014 }
1015 break;
1016 default:
1017 switch (targetType.GetReferenceType())
1018 {
1020 SelectImplicitCasterObjectTargets(effIndex, targetType);
1021 break;
1023 SelectImplicitTargetObjectTargets(effIndex, targetType);
1024 break;
1025 default:
1026 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1027 break;
1028 }
1029 break;
1030 }
1031 break;
1033 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1034 break;
1035 default:
1036 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1037 break;
1038 }
1039}
@ TARGET_SELECT_CATEGORY_CONE
Definition: SpellInfo.h:81
@ TARGET_SELECT_CATEGORY_AREA
Definition: SpellInfo.h:82
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition: SpellInfo.h:78
@ TARGET_SELECT_CATEGORY_NYI
Definition: SpellInfo.h:77
@ TARGET_SELECT_CATEGORY_TRAJ
Definition: SpellInfo.h:83
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition: SpellInfo.h:79
@ TARGET_OBJECT_TYPE_SRC
Definition: SpellInfo.h:99
@ TARGET_REFERENCE_TYPE_TARGET
Definition: SpellInfo.h:90
@ TARGET_REFERENCE_TYPE_CASTER
Definition: SpellInfo.h:89
@ TARGET_REFERENCE_TYPE_DEST
Definition: SpellInfo.h:93
void SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1718
void CheckDst()
Definition: Spell.h:492
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1867
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1211
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1681
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1261
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1041
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1804
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1757
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1097
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition: Spell.cpp:8710
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1343

References ASSERT, CheckDst(), CheckScriptEffectImplicitTargets(), SpellInfo::Effects, SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetSelectionCategory(), GetSpellInfo(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SpellCastTargets::SetSrc(), TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_SRC, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CATEGORY_NYI, and TARGET_SELECT_CATEGORY_TRAJ.

Referenced by SelectSpellTargets().

◆ SelectEffectTypeImplicitTargets()

void Spell::SelectEffectTypeImplicitTargets ( uint8  effIndex)
Todo:
: this is a workaround - target shouldn't be stored in target map for those spells
Todo:
: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
2028{
2029 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
2031 switch (m_spellInfo->Effects[effIndex].Effect)
2032 {
2036 {
2038
2040
2041 if (target && target->ToPlayer())
2042 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2043 }
2044 return;
2045 default:
2046 break;
2047 }
2048
2049 // select spell implicit targets based on effect type
2050 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2051 return;
2052
2053 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
2054
2055 if (!targetMask)
2056 return;
2057
2058 WorldObject* target = nullptr;
2059
2060 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2061 {
2062 // add explicit object target or self to the target map
2064 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2066 {
2068 target = unitTarget;
2069 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2070 {
2071 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2072 {
2074 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2075 target = owner;
2076 }
2077 }
2078 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2079 target = m_caster;
2080 }
2081 if (targetMask & TARGET_FLAG_ITEM_MASK)
2082 {
2084 AddItemTarget(itemTarget, 1 << effIndex);
2085 return;
2086 }
2087 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2088 target = m_targets.GetGOTarget();
2089 break;
2090 // add self to the target map
2092 if (targetMask & TARGET_FLAG_UNIT_MASK)
2093 target = m_caster;
2094 break;
2095 default:
2096 break;
2097 }
2098
2100
2101 if (target)
2102 {
2103 if (target->ToUnit())
2104 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2105 else if (target->ToGameObject())
2106 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2107 }
2108}
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition: SpellInfo.h:144
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition: SpellInfo.h:143
@ TARGET_FLAG_ITEM_MASK
Definition: SpellInfo.h:72
GameObject * ToGameObject()
Definition: Object.h:210
Corpse * GetCorpseTarget() const
Definition: Spell.cpp:295
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition: Spell.cpp:2514
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition: Spell.cpp:2381
void AddItemTarget(Item *item, uint32 effectMask)
Definition: Spell.cpp:2576
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8682
Definition: SpellInfo.h:217

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), EFFECT_IMPLICIT_TARGET_CASTER, EFFECT_IMPLICIT_TARGET_EXPLICIT, SpellInfo::Effects, ObjectAccessor::FindPlayer(), SpellCastTargets::GetCorpseTarget(), SpellCastTargets::GetGOTarget(), SpellCastTargets::GetItemTarget(), Unit::GetTarget(), SpellCastTargets::GetUnitTarget(), Object::IsPlayer(), itemTarget, m_caster, m_spellInfo, m_targets, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_ITEM_MASK, TARGET_FLAG_UNIT_MASK, Object::ToGameObject(), Object::ToPlayer(), Object::ToUnit(), and unitTarget.

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
784{
785 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
786 if (Unit* target = m_targets.GetUnitTarget())
787 {
788 // check for explicit target redirection, for Grounding Totem for example
792 {
793 Unit* redirect;
794 switch (m_spellInfo->DmgClass)
795 {
798 break;
802 break;
803 default:
804 redirect = nullptr;
805 break;
806 }
807 if (redirect && (redirect != target))
808 {
809 m_targets.SetUnitTarget(redirect);
811 }
812 }
813 }
814}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition: Unit.cpp:11013
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition: Unit.cpp:10975

References SpellInfo::DmgClass, SpellInfo::GetExplicitTargetMask(), Unit::GetMagicHitRedirectTarget(), Unit::GetMeleeHitRedirectTarget(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasEffect(), Unit::IsFriendlyTo(), SpellInfo::IsPositive(), m_caster, m_spellFlags, m_spellInfo, m_targets, SpellCastTargets::SetUnitTarget(), SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_FLAG_REDIRECTED, TARGET_FLAG_UNIT, and TARGET_FLAG_UNIT_ENEMY.

Referenced by SelectSpellTargets().

◆ SelectImplicitAreaTargets()

void Spell::SelectImplicitAreaTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1262{
1263 Unit* referer = nullptr;
1264 switch (targetType.GetReferenceType())
1265 {
1269 referer = m_caster;
1270 break;
1272 referer = m_targets.GetUnitTarget();
1273 break;
1275 {
1276 // find last added target for this effect
1277 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1278 {
1279 if (ihit->effectMask & (1 << effIndex))
1280 {
1281 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1282 break;
1283 }
1284 }
1285 break;
1286 }
1287 default:
1288 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1289 return;
1290 }
1291 if (!referer)
1292 return;
1293
1294 Position const* center = nullptr;
1295 switch (targetType.GetReferenceType())
1296 {
1298 center = m_targets.GetSrcPos();
1299 break;
1301 center = m_targets.GetDstPos();
1302 break;
1306 center = referer;
1307 break;
1308 default:
1309 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1310 return;
1311 }
1312
1313 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1314 std::list<WorldObject*> targets;
1315 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1316 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1317
1318 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1319
1320 if (!targets.empty())
1321 {
1322 // Other special target selection goes here
1323 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1324 {
1326 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1327 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1328 maxTargets += (*j)->GetAmount();
1329
1330 Acore::Containers::RandomResize(targets, maxTargets);
1331 }
1332
1333 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1334 {
1335 if (Unit* unitTarget = (*itr)->ToUnit())
1336 AddUnitTarget(unitTarget, effMask, false);
1337 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1338 AddGOTarget(gObjTarget, effMask);
1339 }
1340 }
1341}
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition: SpellAuraDefines.h:340
@ TARGET_REFERENCE_TYPE_SRC
Definition: SpellInfo.h:92
@ TARGET_REFERENCE_TYPE_LAST
Definition: SpellInfo.h:91
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:79
Position const * GetSrcPos() const
Definition: Spell.cpp:363
float RadiusMod
Definition: Spell.h:215
uint32 MaxAffectedTargets
Definition: Spell.h:214
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8668

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDstPos(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetSrcPos(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), m_caster, m_spellInfo, m_spellValue, m_targets, m_UniqueTargetInfo, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SearchAreaTargets(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_LAST, TARGET_REFERENCE_TYPE_SRC, TARGET_REFERENCE_TYPE_TARGET, Object::ToGameObject(), Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterDestTargets()

void Spell::SelectImplicitCasterDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
fix this check
1344{
1346
1347 switch (targetType.GetTarget())
1348 {
1349 case TARGET_DEST_CASTER:
1351 break;
1352 case TARGET_DEST_HOME:
1353 if (Player* playerCaster = m_caster->ToPlayer())
1354 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
1355 break;
1356 case TARGET_DEST_DB:
1357 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1358 {
1361 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1362 else if (st->target_mapId == m_caster->GetMapId())
1363 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1364 }
1365 else
1366 {
1367 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1368 if (WorldObject* target = m_targets.GetObjectTarget())
1369 dest = SpellDestination(*target);
1370 }
1371 break;
1373 {
1374 float min_dis = m_spellInfo->GetMinRange(true);
1375 float max_dis = m_spellInfo->GetMaxRange(true);
1376 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1377 float x, y, z, angle;
1378 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1379 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1381
1382 float ground = m_caster->GetMapHeight(x, y, z, true);
1383 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1385 if (liquidData.Status)
1386 liquidLevel = liquidData.Level;
1387
1388 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1389 {
1392 finish(false);
1393 return;
1394 }
1395
1396 if (ground + 0.75 > liquidLevel)
1397 {
1400 finish(false);
1401 return;
1402 }
1403
1404 if (!m_caster->IsWithinLOS(x, y, z))
1405 {
1408 finish(false);
1409 return;
1410 }
1411
1412 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1413 break;
1414 }
1416 {
1417 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1418 Map* map = m_caster->GetMap();
1419 uint32 mapid = m_caster->GetMapId();
1420 uint32 phasemask = m_caster->GetPhaseMask();
1421 float collisionHeight = m_caster->GetCollisionHeight();
1422 float destz = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1423
1424 Position pos;
1425 Position lastpos;
1426 m_caster->GetPosition(startx, starty, startz, starto);
1427 pos.Relocate(startx, starty, startz, starto);
1428 float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1429 float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1430
1431 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
1432
1433 bool isCasterInWater = m_caster->IsInWater();
1434 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1435 {
1436 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1437 float tstZ1 = 0.0f, tstZ2 = 0.0f, tstZ3 = 0.0f, destz1 = 0.0f, destz2 = 0.0f, destz3 = 0.0f, srange = 0.0f, srange1 = 0.0f, srange2 = 0.0f, srange3 = 0.0f;
1438 float maxtravelDistZ = 2.65f;
1439 float overdistance = 0.0f;
1440 float totalpath = 0.0f;
1441 float beforewaterz = 0.0f;
1442 bool inwater = false;
1443 bool wcol = false;
1444 const float step = 2.0f;
1445 const uint8 numChecks = std::ceil(std::fabs(distance / step));
1446 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1447 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1448 int j = 1;
1449 for (; j < (numChecks + 1); j++)
1450 {
1451 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1452 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1453 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1454 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1455
1456 if (j < 2)
1457 {
1458 prevZ = pos.GetPositionZ();
1459 }
1460 else
1461 {
1462 prevZ = tstZ;
1463 }
1464
1465 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1466 ground = tstZ;
1467
1468 if (!isCasterInWater)
1469 {
1470 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1471 {
1472 if (!(beforewaterz != 0.0f))
1473 {
1474 beforewaterz = prevZ;
1475 }
1476 tstZ = beforewaterz;
1477 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1478 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1479 }
1480 }
1481 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1482 {
1483 prevZ = pos.GetPositionZ();
1484 tstZ = pos.GetPositionZ();
1485 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1486
1487 inwater = true;
1488 if (inwater && (fabs(tstZ - ground) < 2.0f))
1489 {
1490 wcol = true;
1491 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1492 }
1493
1494 // if (j < 2)
1495 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1496 // else
1497 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1498 }
1499
1500 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1501 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1502 {
1503 if (inwater && !IsInWater)
1504 inwater = false;
1505
1506 // highest available point
1507 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1508 // upper or floor
1509 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1510 //lower than floor
1511 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1512
1513 //distance of rays, will select the shortest in 3D
1514 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1515 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1516 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1517 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1518 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1519 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1520
1521 if (srange1 < srange2)
1522 {
1523 tstZ = tstZ1;
1524 srange = srange1;
1525 }
1526 else if (srange3 < srange2)
1527 {
1528 tstZ = tstZ3;
1529 srange = srange3;
1530 }
1531 else
1532 {
1533 tstZ = tstZ2;
1534 srange = srange2;
1535 }
1536
1537 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1538 }
1539
1540 destx = tstX;
1541 desty = tstY;
1542 destz = tstZ;
1543
1544 totalpath += srange;
1545
1546 if (totalpath > distance)
1547 {
1548 overdistance = totalpath - distance;
1549 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1550 }
1551
1552 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1553 // check dynamic collision
1554 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1555
1556 // collision occured
1557 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1558 {
1559 if ((overdistance > 0.0f) && (overdistance < 1.f))
1560 {
1561 destx = prevX + overdistance * cos(pos.GetOrientation());
1562 desty = prevY + overdistance * sin(pos.GetOrientation());
1563 //LOG_ERROR("spells", "(collision) collision occured 1");
1564 }
1565 else
1566 {
1567 // move back a bit
1568 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1569 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1570 //LOG_ERROR("spells", "(collision) collision occured 2");
1571 }
1572
1573 // highest available point
1574 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1575 // upper or floor
1576 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1577 //lower than floor
1578 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1579
1580 //distance of rays, will select the shortest in 3D
1581 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1582 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1583 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1584
1585 if (srange1 < srange2)
1586 destz = destz1;
1587 else if (srange3 < srange2)
1588 destz = destz3;
1589 else
1590 destz = destz2;
1591
1592 if (inwater && destz < prevZ && !wcol)
1593 destz = prevZ;
1594 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1595
1596 // Don't make the player move backward from the xy adjustments by collisions.
1597 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1598 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1599 {
1600 destx = startx;
1601 desty = starty;
1602 destz = startz;
1603 }
1604
1605 break;
1606 }
1607 // we have correct destz now
1608 }
1609
1610 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1611 dest = SpellDestination(lastpos);
1612 }
1613 else
1614 {
1615 float z = pos.GetPositionZ();
1616 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1617 // check dynamic collision
1618 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1619
1620 // collision occured
1621 if (col || dcol)
1622 {
1623 // move back a bit
1624 destx = destx - (0.6 * cos(pos.GetOrientation()));
1625 desty = desty - (0.6 * sin(pos.GetOrientation()));
1626 }
1627
1628 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1629 dest = SpellDestination(lastpos);
1630 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1631 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1632 }
1633 break;
1634 }
1635 default:
1636 {
1637 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1638 float angle = targetType.CalcDirectionAngle();
1639 float objSize = m_caster->GetCombatReach();
1640
1641 switch (targetType.GetTarget())
1642 {
1644 dist = PET_FOLLOW_DIST;
1645 break;
1647 if (dist > objSize)
1648 dist = objSize + (dist - objSize) * float(rand_norm());
1649 break;
1654 {
1655 static float const DefaultTotemDistance = 3.0f;
1656 if (!m_spellInfo->Effects[effIndex].HasRadius())
1657 dist = DefaultTotemDistance;
1658 break;
1659 }
1660 default:
1661 break;
1662 }
1663
1664 if (dist < objSize)
1665 {
1666 dist = objSize;
1667 }
1668
1669 Position pos = dest._position;
1670 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1671
1672 dest.Relocate(pos);
1673 break;
1674 }
1675 }
1676
1677 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1678 m_targets.SetDst(dest);
1679}
#define VMAP_INVALID_HEIGHT_VALUE
Definition: IVMapMgr.h:49
#define MAP_ALL_LIQUIDS
Definition: Map.h:160
@ MOVEMENTFLAG_FALLING
Definition: UnitDefines.h:356
@ SPELL_EFFECT_BIND
Definition: SharedDefines.h:789
@ SPELL_EFFECT_TELEPORT_UNITS
Definition: SharedDefines.h:783
@ TARGET_DEST_CASTER_RANDOM
Definition: SharedDefines.h:1476
@ TARGET_DEST_DB
Definition: SharedDefines.h:1422
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition: SharedDefines.h:1459
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition: SharedDefines.h:1448
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition: SharedDefines.h:1446
@ TARGET_DEST_CASTER_FISHING
Definition: SharedDefines.h:1443
@ TARGET_DEST_CASTER_BACK_LEFT
Definition: SharedDefines.h:1447
@ TARGET_DEST_CASTER_SUMMON
Definition: SharedDefines.h:1436
@ TARGET_DEST_CASTER
Definition: SharedDefines.h:1423
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition: SharedDefines.h:1445
@ TARGET_DEST_CASTER_36
Definition: SharedDefines.h:1440
@ TARGET_DEST_HOME
Definition: SharedDefines.h:1418
@ SPELL_FAILED_TOO_SHALLOW
Definition: SharedDefines.h:1105
static VMapMgr2 * createOrGetVMapMgr()
Definition: VMapFactory.cpp:27
bool GetObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist) override
Definition: VMapMgr2.cpp:201
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition: Object.cpp:3120
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle, float controlZ=0, Position const *startPos=nullptr) const
Definition: Object.cpp:2626
float GetCollisionHeight() const override
Return collision height sent to client.
Definition: Unit.cpp:21071
Definition: Map.h:171
float Level
Definition: Map.h:176
LiquidStatus Status
Definition: Map.h:178
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition: Map.cpp:2040
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType)
Definition: Map.cpp:2201
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition: Map.cpp:2500
bool GetObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist)
Definition: Map.cpp:2478
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8696
Definition: SpellMgr.h:396

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), VMAP::VMapFactory::createOrGetVMapMgr(), DEFAULT_WORLD_OBJECT_SIZE, SpellInfo::Effects, finish(), Unit::GetCollisionHeight(), Unit::GetCombatReach(), Map::GetHeight(), Map::GetLiquidData(), WorldObject::GetMap(), WorldObject::GetMapHeight(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), WorldObject::GetNearPoint(), Map::GetObjectHitPos(), VMAP::VMapMgr2::GetObjectHitPos(), SpellCastTargets::GetObjectTarget(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::HasEffect(), Unit::HasUnitMovementFlag(), SpellInfo::Id, Unit::IsInWater(), Map::IsInWater(), WorldObject::IsWithinLOS(), LiquidData::Level, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAP_ALL_LIQUIDS, MOVEMENTFLAG_FALLING, WorldObject::MovePositionToFirstCollision(), PET_FOLLOW_DIST, rand_norm(), Position::Relocate(), SpellDestination::Relocate(), SendCastResult(), SendChannelUpdate(), SpellCastTargets::SetDst(), SPELL_EFFECT_BIND, SPELL_EFFECT_TELEPORT_UNITS, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_NOT_HERE, SPELL_FAILED_TOO_SHALLOW, sSpellMgr, LiquidData::Status, TARGET_DEST_CASTER, TARGET_DEST_CASTER_36, TARGET_DEST_CASTER_BACK_LEFT, TARGET_DEST_CASTER_BACK_RIGHT, TARGET_DEST_CASTER_FISHING, TARGET_DEST_CASTER_FRONT_LEAP, TARGET_DEST_CASTER_FRONT_LEFT, TARGET_DEST_CASTER_FRONT_RIGHT, TARGET_DEST_CASTER_RANDOM, TARGET_DEST_CASTER_SUMMON, TARGET_DEST_DB, TARGET_DEST_HOME, Object::ToPlayer(), and VMAP_INVALID_HEIGHT_VALUE.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

void Spell::SelectImplicitCasterObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1758{
1759 WorldObject* target = nullptr;
1760 bool checkIfValid = true;
1761
1762 switch (targetType.GetTarget())
1763 {
1764 case TARGET_UNIT_CASTER:
1765 target = m_caster;
1766 checkIfValid = false;
1767 break;
1768 case TARGET_UNIT_MASTER:
1769 target = m_caster->GetCharmerOrOwner();
1770 break;
1771 case TARGET_UNIT_PET:
1772 target = m_caster->GetGuardianPet();
1773 if (!target)
1774 target = m_caster->GetCharm();
1775 break;
1777 if (m_caster->IsSummon())
1778 target = m_caster->ToTempSummon()->GetSummonerUnit();
1779 break;
1781 target = m_caster->GetVehicleBase();
1782 break;
1792 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1793 break;
1794 default:
1795 break;
1796 }
1797
1798 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1799
1800 if (target && target->ToUnit())
1801 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1802}
@ TARGET_UNIT_PASSENGER_1
Definition: SharedDefines.h:1501
@ TARGET_UNIT_PASSENGER_6
Definition: SharedDefines.h:1506
@ TARGET_UNIT_VEHICLE
Definition: SharedDefines.h:1498
@ TARGET_UNIT_PASSENGER_2
Definition: SharedDefines.h:1502
@ TARGET_UNIT_PASSENGER_4
Definition: SharedDefines.h:1504
@ TARGET_UNIT_PASSENGER_7
Definition: SharedDefines.h:1507
@ TARGET_UNIT_MASTER
Definition: SharedDefines.h:1431
@ TARGET_UNIT_PASSENGER_5
Definition: SharedDefines.h:1505
@ TARGET_UNIT_PASSENGER_3
Definition: SharedDefines.h:1503
@ TARGET_UNIT_SUMMONER
Definition: SharedDefines.h:1496
@ TARGET_UNIT_PASSENGER_0
Definition: SharedDefines.h:1500
Unit * GetSummonerUnit() const
Definition: TemporarySummon.cpp:44
Unit * GetVehicleBase() const
Definition: Unit.cpp:18697
Unit * GetPassenger(int8 seatId) const
Definition: Vehicle.cpp:224

References AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), Unit::GetCharm(), Unit::GetCharmerOrOwner(), Unit::GetGuardianPet(), Vehicle::GetPassenger(), TempSummon::GetSummonerUnit(), SpellImplicitTargetInfo::GetTarget(), Unit::GetVehicleBase(), Unit::GetVehicleKit(), Object::IsCreature(), Unit::IsSummon(), Unit::IsVehicle(), m_caster, TARGET_UNIT_CASTER, TARGET_UNIT_MASTER, TARGET_UNIT_PASSENGER_0, TARGET_UNIT_PASSENGER_1, TARGET_UNIT_PASSENGER_2, TARGET_UNIT_PASSENGER_3, TARGET_UNIT_PASSENGER_4, TARGET_UNIT_PASSENGER_5, TARGET_UNIT_PASSENGER_6, TARGET_UNIT_PASSENGER_7, TARGET_UNIT_PET, TARGET_UNIT_SUMMONER, TARGET_UNIT_VEHICLE, Object::ToCreature(), Unit::ToTempSummon(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1827{
1828 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1829 if (Player* modOwner = m_caster->GetSpellModOwner())
1830 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1831
1832 if (maxTargets > 1)
1833 {
1834 // mark damage multipliers as used
1835 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1836 if (effMask & (1 << k))
1837 m_damageMultipliers[k] = 1.0f;
1838 m_applyMultiplierMask |= effMask;
1839
1840 std::list<WorldObject*> targets;
1841 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1842 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1843
1844 // Chain primary target is added earlier
1845 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1846
1847 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1848 if (Unit* unitTarget = (*itr)->ToUnit())
1849 AddUnitTarget(unitTarget, effMask, false);
1850 }
1851}
@ SPELLMOD_JUMP_TARGETS
Definition: SpellDefines.h:94
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition: SharedDefines.h:1449
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
Definition: Spell.cpp:2196

References AddUnitTarget(), CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetSelectionCategory(), Unit::GetSpellModOwner(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, m_applyMultiplierMask, m_caster, m_damageMultipliers, m_spellInfo, MAX_SPELL_EFFECTS, SearchChainTargets(), SPELLMOD_JUMP_TARGETS, TARGET_UNIT_TARGET_CHAINHEAL_ALLY, Object::ToUnit(), and unitTarget.

Referenced by SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ SelectImplicitChannelTargets()

void Spell::SelectImplicitChannelTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1042{
1043 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1044 {
1045 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1046 return;
1047 }
1048
1049 switch (targetType.GetTarget())
1050 {
1052 {
1053 // Xinef: All channel selectors have needed data passed in m_targets structure
1055 if (target)
1056 {
1057 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1058 // unit target may be no longer avalible - teleported out of map for example
1059 if (target && target->ToUnit())
1060 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1061 }
1062 else
1063 {
1064 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1065 }
1066 break;
1067 }
1072 {
1073 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1074 if (target)
1075 m_targets.SetDst(*target);
1076 }
1078 {
1079 if (channeledSpell->m_targets.GetUnitTarget())
1080 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1081 }
1082 else //if (!m_targets.HasDst())
1083 {
1084 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1085 }
1086 break;
1088 if (GetOriginalCaster())
1090 break;
1091 default:
1092 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1093 break;
1094 }
1095}
@ TARGET_DEST_CHANNEL_TARGET
Definition: SharedDefines.h:1480
@ TARGET_UNIT_CHANNEL_TARGET
Definition: SharedDefines.h:1481
@ TARGET_DEST_CHANNEL_CASTER
Definition: SharedDefines.h:1510
WorldObject * GetObjectTargetChannel(Unit *caster) const
Definition: Spell.cpp:465
SpellDestination const * GetDstChannel() const
Definition: Spell.cpp:475
bool HasDstChannel() const
Definition: Spell.cpp:470

References AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), CURRENT_CHANNELED_SPELL, Unit::GetCurrentSpell(), SpellCastTargets::GetDstChannel(), SpellCastTargets::GetObjectTargetChannel(), GetOriginalCaster(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetTarget(), SpellCastTargets::HasDstChannel(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCaster, m_spellInfo, m_targets, SpellCastTargets::SetDst(), TARGET_DEST_CHANNEL_CASTER, TARGET_DEST_CHANNEL_TARGET, TARGET_REFERENCE_TYPE_CASTER, TARGET_UNIT_CHANNEL_TARGET, and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitConeTargets()

void Spell::SelectImplicitConeTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1212{
1213 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1214 {
1215 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1216 return;
1217 }
1218 std::list<WorldObject*> targets;
1219 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1220 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1221 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1222 float coneAngle = M_PI / 2;
1223 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1224
1225 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1226 {
1227 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1228 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1229 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1230
1231 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1232
1233 if (!targets.empty())
1234 {
1235 // Other special target selection goes here
1236 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1237 {
1239 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1240 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1241 maxTargets += (*j)->GetAmount();
1242
1243 Acore::Containers::RandomResize(targets, maxTargets);
1244 }
1245
1246 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1247 {
1248 if (Unit* unit = (*itr)->ToUnit())
1249 {
1250 AddUnitTarget(unit, effMask, false);
1251 }
1252 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1253 {
1254 AddGOTarget(gObjTarget, effMask);
1255 }
1256 }
1257 }
1258 }
1259}
SpellTargetCheckTypes
Definition: SpellInfo.h:113
SpellTargetObjectTypes
Definition: SpellInfo.h:97

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), GetSearcherTypeMask(), m_caster, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitDestDestTargets()

void Spell::SelectImplicitDestDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1719{
1720 // set destination to caster if no dest provided
1721 // can only happen if previous destination target could not be set for some reason
1722 // (not found nearby target, or channel target for example
1723 // maybe we should abort the spell in such case?
1724 CheckDst();
1725
1727
1728 switch (targetType.GetTarget())
1729 {
1733 case TARGET_DEST_DEST:
1734 return;
1735 case TARGET_DEST_TRAJ:
1736 SelectImplicitTrajTargets(effIndex, targetType);
1737 return;
1738 default:
1739 {
1740 float angle = targetType.CalcDirectionAngle();
1741 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1742 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1743 dist *= float(rand_norm());
1744
1745 Position pos = dest._position;
1746 m_caster->MovePosition(pos, dist, angle);
1747
1748 dest.Relocate(pos);
1749 break;
1750 }
1751 }
1752
1753 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1754 m_targets.ModDst(dest);
1755}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition: SharedDefines.h:1432
@ TARGET_DEST_DEST_RANDOM
Definition: SharedDefines.h:1490
@ TARGET_DEST_DEST
Definition: SharedDefines.h:1491
@ TARGET_DEST_DYNOBJ_NONE
Definition: SharedDefines.h:1492
@ TARGET_DEST_DYNOBJ_ALLY
Definition: SharedDefines.h:1433
@ TARGET_DEST_TRAJ
Definition: SharedDefines.h:1493
void MovePosition(Position &pos, float dist, float angle, bool disableWarning=false)
Definition: Object.cpp:2776
void ModDst(Position const &pos)
Definition: Spell.cpp:437
SpellDestination const * GetDst() const
Definition: Spell.cpp:397

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), CheckDst(), SpellInfo::Effects, SpellCastTargets::GetDst(), SpellImplicitTargetInfo::GetTarget(), m_caster, m_spellInfo, m_targets, SpellCastTargets::ModDst(), WorldObject::MovePosition(), rand_norm(), SpellDestination::Relocate(), SelectImplicitTrajTargets(), TARGET_DEST_DEST, TARGET_DEST_DEST_RANDOM, TARGET_DEST_DYNOBJ_ALLY, TARGET_DEST_DYNOBJ_ENEMY, TARGET_DEST_DYNOBJ_NONE, and TARGET_DEST_TRAJ.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitNearbyTargets()

void Spell::SelectImplicitNearbyTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1098{
1099 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1100 {
1101 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1102 return;
1103 }
1104
1105 float range = 0.0f;
1106 switch (targetType.GetCheckType())
1107 {
1108 case TARGET_CHECK_ENEMY:
1109 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1110 break;
1111 case TARGET_CHECK_ALLY:
1112 case TARGET_CHECK_PARTY:
1113 case TARGET_CHECK_RAID:
1115 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1116 break;
1117 case TARGET_CHECK_ENTRY:
1120 break;
1121 default:
1122 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1123 break;
1124 }
1125
1126 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1127
1128 // handle emergency case - try to use other provided targets if no conditions provided
1129 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1130 {
1131 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID {}, effect {} - selecting default targets", m_spellInfo->Id, effIndex);
1132 switch (targetType.GetObjectType())
1133 {
1136 {
1137 if (focusObject)
1138 AddGOTarget(focusObject, effMask);
1139 return;
1140 }
1141 break;
1144 {
1145 if (focusObject)
1147 return;
1148 }
1149 break;
1150 default:
1151 break;
1152 }
1153 }
1154
1155 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1156 if (!target)
1157 {
1158 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1159 return;
1160 }
1161
1162 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1163 if (!target)
1164 {
1165 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1166 return;
1167 }
1168
1169 switch (targetType.GetObjectType())
1170 {
1172 {
1173 if (Unit* unit = target->ToUnit())
1174 {
1175 AddUnitTarget(unit, effMask, true, false);
1176 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1177 // and if channeled spell has target 77, it requires unitTarget, set it here!
1178 // xinef: if we have NO unit target
1179 if (!m_targets.GetUnitTarget())
1180 {
1182 }
1183 }
1184 else
1185 {
1186 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected unit, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1187 return;
1188 }
1189 break;
1190 }
1192 if (GameObject* gobjTarget = target->ToGameObject())
1193 AddGOTarget(gobjTarget, effMask);
1194 else
1195 {
1196 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected gameobject, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1197 return;
1198 }
1199 break;
1201 m_targets.SetDst(*target);
1202 break;
1203 default:
1204 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1205 break;
1206 }
1207
1208 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1209}
@ TARGET_CHECK_PARTY
Definition: SpellInfo.h:118
@ TARGET_CHECK_ENEMY
Definition: SpellInfo.h:116
@ TARGET_CHECK_DEFAULT
Definition: SpellInfo.h:114
@ TARGET_CHECK_RAID_CLASS
Definition: SpellInfo.h:120
@ TARGET_CHECK_ALLY
Definition: SpellInfo.h:117
@ TARGET_CHECK_RAID
Definition: SpellInfo.h:119
WorldObject * SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
Definition: Spell.cpp:2174
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition: Spell.cpp:1826

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellInfo::Effects, focusObject, SpellImplicitTargetInfo::GetCheckType(), SpellInfo::GetMaxRange(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetUnitTarget(), SpellInfo::Id, SpellInfo::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, SpellInfo::RequiresSpellFocus, SearchNearbyTarget(), SelectImplicitChainTargets(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), TARGET_CHECK_ALLY, TARGET_CHECK_DEFAULT, TARGET_CHECK_ENEMY, TARGET_CHECK_ENTRY, TARGET_CHECK_PARTY, TARGET_CHECK_RAID, TARGET_CHECK_RAID_CLASS, TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetDestTargets()

void Spell::SelectImplicitTargetDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1682{
1684
1685 SpellDestination dest(*target);
1686
1687 switch (targetType.GetTarget())
1688 {
1691 break;
1692 default:
1693 {
1694 float angle = targetType.CalcDirectionAngle();
1695 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1696 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1697 {
1698 dist *= float(rand_norm());
1699 }
1700
1701 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1702 {
1704 }
1705
1706 Position pos = dest._position;
1707 target->MovePositionToFirstCollision(pos, dist, angle);
1708
1709 dest.Relocate(pos);
1710 break;
1711 }
1712 }
1713
1714 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1715 m_targets.SetDst(dest);
1716}
@ UNIT_FIELD_BOUNDINGRADIUS
Definition: UpdateFields.h:122
@ TARGET_DEST_TARGET_ANY
Definition: SharedDefines.h:1467
@ TARGET_DEST_TARGET_BACK
Definition: SharedDefines.h:1469
@ TARGET_DEST_TARGET_RANDOM
Definition: SharedDefines.h:1478
@ TARGET_DEST_TARGET_ENEMY
Definition: SharedDefines.h:1457

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), SpellInfo::Effects, Object::GetFloatValue(), SpellCastTargets::GetObjectTarget(), SpellImplicitTargetInfo::GetTarget(), m_spellInfo, m_targets, WorldObject::MovePositionToFirstCollision(), rand_norm(), SpellDestination::Relocate(), SpellCastTargets::SetDst(), TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_BACK, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TARGET_RANDOM, and UNIT_FIELD_BOUNDINGRADIUS.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetObjectTargets()

void Spell::SelectImplicitTargetObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1805{
1806 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1807
1809
1810 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1811
1812 if (target)
1813 {
1814 if (Unit* unit = target->ToUnit())
1815 AddUnitTarget(unit, 1 << effIndex, true, false);
1816 else if (GameObject* gobj = target->ToGameObject())
1817 AddGOTarget(gobj, 1 << effIndex);
1818
1819 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1820 }
1821 // Script hook can remove object target and we would wrongly land here
1822 else if (Item* item = m_targets.GetItemTarget())
1823 AddItemTarget(item, 1 << effIndex);
1824}

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), m_targets, SelectImplicitChainTargets(), Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTrajTargets()

void Spell::SelectImplicitTrajTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
: all calculation should be based on src instead of m_caster
1868{
1869 if (!m_targets.HasTraj())
1870 return;
1871
1872 float dist2d = m_targets.GetDist2d();
1873 if (!dist2d)
1874 return;
1875
1876 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - m_targets.GetSrcPos()->m_positionZ;
1877
1878 // xinef: supply correct target type, DEST_DEST and similar are ALWAYS undefined
1879 // xinef: correct target is stored in TRIGGERED SPELL, however as far as i noticed, all checks are ENTRY, ENEMY
1880 std::list<WorldObject*> targets;
1881 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrcPos(), m_caster, m_spellInfo, TARGET_CHECK_ENEMY /*targetCheckType*/, m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1883 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrcPos(), dist2d);
1884 if (targets.empty())
1885 return;
1886
1888
1889 float b = tangent(m_targets.GetElevation());
1890 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1891 if (a > -0.0001f)
1892 a = 0;
1893
1894 LOG_DEBUG("spells", "Spell::SelectTrajTargets: a {} b {}", a, b);
1895
1896 // Xinef: hack for distance, many trajectory spells have RangeEntry 1 (self)
1897 float bestDist = m_spellInfo->GetMaxRange(false) * 2;
1898 if (bestDist < 1.0f)
1899 bestDist = 300.0f;
1900
1901 std::list<WorldObject*>::const_iterator itr = targets.begin();
1902 for (; itr != targets.end(); ++itr)
1903 {
1904 if (Unit* unitTarget = (*itr)->ToUnit())
1905 if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || (unitTarget)->GetVehicle())//(*itr)->IsOnVehicle(m_caster))
1906 continue;
1907
1908 const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
1910 const float objDist2d = std::fabs(m_targets.GetSrcPos()->GetExactDist2d(*itr) * cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr)));
1911 const float dz = std::fabs((*itr)->GetPositionZ() - m_targets.GetSrcPos()->m_positionZ);
1912
1913 LOG_DEBUG("spells", "Spell::SelectTrajTargets: check {}, dist between {} {}, height between {} {}.",
1914 (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);
1915
1916 float dist = objDist2d - size;
1917 float height = dist * (a * dist + b);
1918
1919 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);
1920
1921 if (dist < bestDist && height < dz + size && height > dz - size)
1922 {
1923 bestDist = dist > 0 ? dist : 0;
1924 break;
1925 }
1926
1927#define CHECK_DIST {\
1928 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);\
1929 if (dist > bestDist)\
1930 continue;\
1931 if (dist < objDist2d + size && dist > objDist2d - size)\
1932 {\
1933 bestDist = dist;\
1934 break;\
1935 }\
1936 }
1937
1938 // RP-GG only, search in straight line, as item have no trajectory
1939 if (m_CastItem)
1940 {
1941 if (dist < bestDist && std::fabs(dz) < 6.0f) // closes target, also check Z difference)
1942 {
1943 bestDist = dist;
1944 break;
1945 }
1946
1947 continue;
1948 }
1949
1950 if (!a)
1951 {
1952 // Xinef: everything remade
1953 dist = m_targets.GetSrcPos()->GetExactDist(*itr);
1954 height = m_targets.GetSrcPos()->GetExactDist2d(*itr) * b;
1955
1956 if (height < dz + size * (b + 1) && height > dz - size * (b + 1) && dist < bestDist)
1957 {
1958 bestDist = dist;
1959 break;
1960 }
1961
1962 continue;
1963 }
1964
1965 height = dz - size;
1966 float sqrt1 = b * b + 4 * a * height;
1967 if (sqrt1 > 0)
1968 {
1969 sqrt1 = std::sqrt(sqrt1);
1970 dist = (sqrt1 - b) / (2 * a);
1971 CHECK_DIST;
1972 }
1973
1974 height = dz + size;
1975 float sqrt2 = b * b + 4 * a * height;
1976 if (sqrt2 > 0)
1977 {
1978 sqrt2 = std::sqrt(sqrt2);
1979 dist = (sqrt2 - b) / (2 * a);
1980 CHECK_DIST;
1981
1982 dist = (-sqrt2 - b) / (2 * a);
1983 CHECK_DIST;
1984 }
1985
1986 if (sqrt1 > 0)
1987 {
1988 dist = (-sqrt1 - b) / (2 * a);
1989 CHECK_DIST;
1990 }
1991 }
1992
1994 {
1995 float x = m_targets.GetSrcPos()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
1996 float y = m_targets.GetSrcPos()->m_positionY + std::sin(m_caster->GetOrientation()) * bestDist;
1997 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
1998
1999 if (itr != targets.end())
2000 {
2001 float distSq = (*itr)->GetExactDistSq(x, y, z);
2002 float sizeSq = (*itr)->GetObjectSize();
2003 sizeSq *= sizeSq;
2004 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2005 if (distSq > sizeSq)
2006 {
2007 float factor = 1 - std::sqrt(sizeSq / distSq);
2008 x += factor * ((*itr)->GetPositionX() - x);
2009 y += factor * ((*itr)->GetPositionY() - y);
2010 z += factor * ((*itr)->GetPositionZ() - z);
2011
2012 distSq = (*itr)->GetExactDistSq(x, y, z);
2013 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2014 }
2015 }
2016
2017 Position trajDst;
2018 trajDst.Relocate(x, y, z, m_caster->GetOrientation());
2020 dest.Relocate(trajDst);
2021
2022 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
2023 m_targets.ModDst(dest);
2024 }
2025}
float tangent(float x)
Definition: Spell.cpp:1853
#define CHECK_DIST
Definition: Object.h:696
bool IsOnVehicle(Unit const *vehicle) const
Definition: Unit.h:1688
float GetElevation() const
Definition: Spell.h:168

References CallScriptDestinationTargetSelectHandlers(), CHECK_DIST, SpellInfo::Effects, SpellCastTargets::GetDist2d(), SpellCastTargets::GetDst(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetElevation(), Position::GetExactDist(), Position::GetExactDist2d(), SpellInfo::GetMaxRange(), Position::GetOrientation(), Position::GetRelativeAngle(), SpellCastTargets::GetSrcPos(), GRID_MAP_TYPE_MASK_ALL, SpellCastTargets::HasTraj(), Unit::IsOnVehicle(), LOG_DEBUG, m_caster, m_CastItem, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_spellInfo, m_targets, SpellCastTargets::ModDst(), Position::Relocate(), SpellDestination::Relocate(), tangent(), TARGET_CHECK_ENEMY, Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ SelectSpellTargets()

void Spell::SelectSpellTargets ( )
817{
818 // select targets for cast phase
820
821 uint32 processedAreaEffectsMask = 0;
822 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
823 {
824 // not call for empty effect.
825 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
826 if (!m_spellInfo->Effects[i].IsEffect())
827 continue;
828
829 // set expected type of implicit targets to be sent to client
830 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
831 if (implicitTargetMask & TARGET_FLAG_UNIT)
833 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
835
836 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
837 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
838
839 // Select targets of effect based on effect type
840 // those are used when no valid target could be added for spell effect based on spell target type
841 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
842 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
843 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
845
846 if (m_targets.HasDst())
848
850 {
851 // maybe do this for all spells?
852 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
853 {
855 finish(false);
856 return;
857 }
858
859 uint8 mask = (1 << i);
860 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
861 {
862 if (ihit->effectMask & mask)
863 {
865 break;
866 }
867 }
868 }
869 else if (m_auraScaleMask)
870 {
871 bool checkLvl = !m_UniqueTargetInfo.empty();
872 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
873 {
874 // remove targets which did not pass min level check
875 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
876 {
877 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
878 return true;
879 }
880
881 return false;
882 }), std::end(m_UniqueTargetInfo));
883
884 if (checkLvl && m_UniqueTargetInfo.empty())
885 {
887 finish(false);
888 }
889 }
890 }
891
892 if (uint64 dstDelay = CalculateDelayMomentForDst())
893 m_delayMoment = dstDelay;
894}
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition: SpellInfo.cpp:30
@ TARGET_FLAG_GAMEOBJECT
Definition: SpellInfo.h:57
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition: SpellInfo.h:60
void SetTargetFlag(SpellCastTargetFlags flag)
Definition: Spell.h:120
void SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
Definition: Spell.cpp:923
void SelectExplicitTargets()
Definition: Spell.cpp:783
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition: Spell.cpp:2605
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition: Spell.cpp:2027

References AddDestTarget(), CalculateDelayMomentForDst(), TargetInfo::effectMask, SpellInfo::Effects, finish(), focusObject, SpellCastTargets::GetDst(), GetTargetFlagMask(), SpellCastTargets::HasDst(), SpellInfo::IsChanneled(), m_auraScaleMask, m_channelTargetEffectMask, m_delayMoment, m_spellInfo, m_targets, m_UniqueGOTargetInfo, m_UniqueItemInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SendCastResult(), SpellCastTargets::SetTargetFlag(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_LOWLEVEL, TARGET_FLAG_GAMEOBJECT, TARGET_FLAG_GAMEOBJECT_ITEM, and TARGET_FLAG_UNIT.

Referenced by _cast(), CanAutoCast(), spell_dk_raise_dead::CheckCast(), and prepare().

◆ SendCastResult() [1/2]

void Spell::SendCastResult ( Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError = SPELL_CUSTOM_ERROR_NONE 
)
static
4669{
4670 if (result == SPELL_CAST_OK)
4671 return;
4672
4673 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4674 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4675
4676 caster->GetSession()->SendPacket(&data);
4677}
@ SMSG_CAST_FAILED
Definition: Opcodes.h:334
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition: Spell.cpp:4563

References Player::GetSession(), WorldSession::SendPacket(), SMSG_CAST_FAILED, SPELL_CAST_OK, and WriteCastResultInfo().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), Player::CastItemUseSpell(), spell_q12237_rescue_villager::CheckCast(), spell_q12237_drop_off_villager::CheckCast(), spell_dk_raise_dead::CheckReagents(), spell_putricide_mutation_init::CheckRequirement(), EffectApplyGlyph(), EffectDuel(), EffectOpenLock(), EffectTaunt(), SpellScript::FinishCast(), go_soulwell::go_soulwellAI::GossipHello(), WorldSession::HandleAcceptTradeOpcode(), spell_the_flag_of_ownership::HandleFinish(), WorldSession::HandlePetActionHelper(), spell_putricide_mutated_transformation::HandleSummon(), misc_commandscript::HandleUnstuckCommand(), icecrown_citadel_teleport::OnGossipSelect(), at_frozen_throne_teleport::OnTrigger(), item_petrov_cluster_bombs::OnUse(), item_only_for_flight::OnUse(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and SendCastResult().

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4680{
4681 if (result == SPELL_CAST_OK)
4682 return;
4683
4684 if (!m_caster->IsPlayer() || m_caster->IsCharmed())
4685 return;
4686
4687 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4688 return;
4689
4690 // Xinef: override every possible result, except for gm fail result... breaks many things and goes unnoticed because of this and makes me rage when i find this out
4692 result = SPELL_FAILED_DONT_REPORT;
4693
4695}
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition: SpellDefines.h:147
@ SPELL_FAILED_BM_OR_INVISGOD
Definition: SharedDefines.h:1108
bool IsCharmed() const
Definition: Unit.h:1278

References Player::GetSession(), HasTriggeredCastFlag(), Unit::IsCharmed(), Object::IsPlayer(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::PlayerLoading(), SendCastResult(), SPELL_CAST_OK, SPELL_FAILED_BM_OR_INVISGOD, SPELL_FAILED_DONT_REPORT, Object::ToPlayer(), and TRIGGERED_DONT_REPORT_CAST_ERROR.

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5206{
5207 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5208 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5209 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5210 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5211
5212 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5213 data << m_caster->GetPackGUID();
5214 data << uint32(m_spellInfo->Id);
5215 data << uint32(duration);
5216
5217 m_caster->SendMessageToSet(&data, true);
5218
5221
5222 m_timer = duration;
5223 if (channelTarget)
5225
5227}
@ MSG_CHANNEL_START
Definition: Opcodes.h:343

References WorldObject::FindMap(), Object::GetGUID(), SpellCastTargets::GetObjectTargetGUID(), Object::GetPackGUID(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, m_targets, m_timer, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MSG_CHANNEL_START, Player::NeedSendSpectatorData(), SpellInfo::NeedsExplicitUnitTarget(), ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), Object::SetGuidValue(), Unit::SetUInt32Value(), Object::ToPlayer(), UNIT_CHANNEL_SPELL, and UNIT_FIELD_CHANNEL_OBJECT.

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5174{
5175 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5176 data << m_caster->GetPackGUID();
5177 data << uint8(m_cast_count);
5178 data << uint32(m_spellInfo->Id);
5179 data << uint8(result);
5180 m_caster->SendMessageToSet(&data, true);
5181
5182 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5183 data << m_caster->GetPackGUID();
5184 data << uint8(m_cast_count);
5185 data << uint32(m_spellInfo->Id);
5186 data << uint8(result);
5187 m_caster->SendMessageToSet(&data, true);
5188}
@ SMSG_SPELL_FAILURE
Definition: Opcodes.h:337
@ SMSG_SPELL_FAILED_OTHER
Definition: Opcodes.h:708

References Object::GetPackGUID(), SpellInfo::Id, WorldPacket::Initialize(), m_cast_count, m_caster, m_spellInfo, WorldObject::SendMessageToSet(), SMSG_SPELL_FAILED_OTHER, and SMSG_SPELL_FAILURE.

Referenced by _cast(), Unit::AttackerStateUpdate(), and cancel().

◆ SendLogExecute()

void Spell::SendLogExecute ( )
5073{
5074 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5075
5076 data << m_caster->GetPackGUID();
5077
5078 data << uint32(m_spellInfo->Id);
5079
5080 uint8 effCount = 0;
5081 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5082 {
5083 if (m_effectExecuteData[i])
5084 ++effCount;
5085 }
5086
5087 if (!effCount)
5088 return;
5089
5090 data << uint32(effCount);
5091 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5092 {
5093 if (!m_effectExecuteData[i])
5094 continue;
5095
5096 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5097
5098 data.append(*m_effectExecuteData[i]);
5099
5100 delete m_effectExecuteData[i];
5101 m_effectExecuteData[i] = nullptr;
5102 }
5103 m_caster->SendMessageToSet(&data, true);
5104}
@ SMSG_SPELLLOGEXECUTE
Definition: Opcodes.h:618

References ByteBuffer::append(), SpellInfo::Effects, Object::GetPackGUID(), SpellInfo::Id, m_caster, m_effectExecuteData, m_spellInfo, MAX_SPELL_EFFECTS, WorldObject::SendMessageToSet(), and SMSG_SPELLLOGEXECUTE.

Referenced by FinishTargetProcessing().

◆ SendLoot()

void Spell::SendLoot ( ObjectGuid  guid,
LootType  loottype 
)
protected
1998{
1999 Player* player = m_caster->ToPlayer();
2000 if (!player)
2001 return;
2002
2003 if (gameObjTarget)
2004 {
2005 // Players shouldn't be able to loot gameobjects that are currently despawned
2006 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2007 {
2008 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2009 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2010 return;
2011 }
2012 // special case, already has GossipHello inside so return and avoid calling twice
2014 {
2016 return;
2017 }
2018
2019 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2020 return;
2021
2022 if (gameObjTarget->AI()->GossipHello(player, false))
2023 return;
2024
2025 switch (gameObjTarget->GetGoType())
2026 {
2028 gameObjTarget->UseDoorOrButton(0, false, player);
2029 return;
2031 gameObjTarget->UseDoorOrButton(0, false, player);
2032
2033 // Xinef: properly link possible traps
2034 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2035 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2036 return;
2040 return;
2041
2043 // triggering linked GO
2046 return;
2047
2049 // triggering linked GO
2050 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2052
2053 // Don't return, let loots been taken
2054 default:
2055 break;
2056 }
2057 }
2058
2059 // Send loot
2060 player->SendLoot(guid, loottype);
2061}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition: SharedDefines.h:1568
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition: SharedDefines.h:1562
virtual bool GossipHello(Player *, bool)
Definition: GameObjectAI.h:55
bool isSpawned() const
Definition: GameObject.h:190
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition: GameObject.cpp:1385
uint32 gossipID
Definition: GameObjectData.h:72
uint32 linkedTrap
Definition: GameObjectData.h:59
struct GameObjectTemplate::@227::@232 chest
struct GameObjectTemplate::@227::@236 spellFocus
uint32 linkedTrapId
Definition: GameObjectData.h:90
struct GameObjectTemplate::@227::@231 questgiver
void SendPreparedGossip(WorldObject *source)
Definition: PlayerGossip.cpp:209
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition: PlayerGossip.cpp:32

References GameObject::AI(), GameObjectTemplate::button, GameObjectTemplate::chest, GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_QUESTGIVER, GAMEOBJECT_TYPE_SPELL_FOCUS, gameObjTarget, GameObject::GetGOInfo(), GameObject::GetGoType(), Object::GetGUID(), WorldObject::GetName(), GameObjectAI::GossipHello(), GameObjectTemplate::gossipID, Player::IsGameMaster(), GameObject::isSpawned(), GameObjectTemplate::linkedTrap, GameObjectTemplate::linkedTrapId, LOG_ERROR, m_caster, Player::PrepareGossipMenu(), GameObjectTemplate::questgiver, Player::SendLoot(), Player::SendPreparedGossip(), GameObjectTemplate::spellFocus, sScriptMgr, Object::ToPlayer(), ObjectGuid::ToString(), GameObject::TriggeringLinkedGameObject(), GameObject::Use(), and GameObject::UseDoorOrButton().

Referenced by EffectOpenLock().

◆ SendPetCastResult()

void Spell::SendPetCastResult ( SpellCastResult  result)
4698{
4699 if (result == SPELL_CAST_OK)
4700 return;
4701
4702 Unit* owner = m_caster->GetCharmerOrOwner();
4703 if (!owner)
4704 return;
4705
4706 Player* player = owner->ToPlayer();
4707 if (!player)
4708 return;
4709
4710 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4712
4713 player->GetSession()->SendPacket(&data);
4714}
@ SMSG_PET_CAST_FAILED
Definition: Opcodes.h:342

References Unit::GetCharmerOrOwner(), Player::GetSession(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::SendPacket(), SMSG_PET_CAST_FAILED, SPELL_CAST_OK, Object::ToPlayer(), and WriteCastResultInfo().

Referenced by WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player target)
5230{
5231 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5232 // for player resurrections the name is looked up by guid
5233 std::string const sentName(m_caster->IsPlayer()
5234 ? ""
5236
5237 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5238 data << m_caster->GetGUID();
5239 data << uint32(sentName.size() + 1);
5240
5241 data << sentName;
5242 data << uint8(0); // null terminator
5243
5244 data << uint8(m_caster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5245 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5247 data << uint32(0);
5248 target->GetSession()->SendPacket(&data);
5249}
@ SPELL_ATTR3_NO_RES_TIMER
Definition: SharedDefines.h:497
@ SMSG_RESURRECT_REQUEST
Definition: Opcodes.h:377
virtual std::string const & GetNameForLocaleIdx(LocaleConstant) const
Definition: Object.h:461
LocaleConstant GetSessionDbLocaleIndex() const
Definition: WorldSession.h:498

References Object::GetGUID(), WorldObject::GetNameForLocaleIdx(), Player::GetSession(), WorldSession::GetSessionDbLocaleIndex(), SpellInfo::HasAttribute(), Object::IsPlayer(), m_caster, m_spellInfo, WorldSession::SendPacket(), SMSG_RESURRECT_REQUEST, and SPELL_ATTR3_NO_RES_TIMER.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

void Spell::SendSpellCooldown ( )
4355{
4356 // xinef: properly add creature cooldowns
4357 if (!m_caster->IsPlayer())
4358 {
4360 {
4361 // xinef: this should be added here
4362 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4363
4364 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4367 {
4368 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4369 data << m_caster->GetGUID();
4371 data << uint32(m_spellInfo->Id);
4373 player->SendDirectMessage(&data);
4374 }
4375 }
4376 return;
4377 }
4378
4379 Player* _player = m_caster->ToPlayer();
4380
4381 // mana/health/etc potions, disabled by client (until combat out as declarate)
4383 {
4384 // need in some way provided data for Spell::finish SendCooldownEvent
4385 _player->SetLastPotionId(m_CastItem->GetEntry());
4386 return;
4387 }
4388
4389 // have infinity cooldown but set at aura apply
4390 // do not set cooldown for triggered spells (needed by reincarnation)
4395 return;
4396
4398}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition: Unit.h:617
@ SMSG_SPELL_COOLDOWN
Definition: Opcodes.h:338
void SetLastPotionId(uint32 item_id)
Definition: Player.h:1795
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition: Player.cpp:10907
uint32 RecoveryTime
Definition: SpellInfo.h:348
bool RequireCooldownInfo() const
Definition: SpellInfo.cpp:1181

References Player::AddSpellAndCategoryCooldowns(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetEntry(), Object::GetGUID(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsCooldownStartedOnEvent(), SpellInfo::IsPassive(), Object::IsPlayer(), Item::IsPotion(), m_caster, m_CastItem, m_spellInfo, SpellInfo::RecoveryTime, SpellInfo::RequireCooldownInfo(), Player::SetLastPotionId(), SMSG_SPELL_COOLDOWN, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, Object::ToPlayer(), TRIGGERED_IGNORE_EFFECTS, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

Referenced by _cast().

◆ SendSpellGo()

void Spell::SendSpellGo ( )
4797{
4798 // not send invisible spell casting
4799 if (!IsNeedSendToClient(true))
4800 return;
4801
4802 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4803
4804 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4805
4806 // triggered spells with spell visual != 0
4808 castFlags |= CAST_FLAG_PENDING;
4809
4811 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4812
4813 // should only be sent to self, but the current messaging doesn't make that possible
4814 if (m_caster->IsPlayer() || m_caster->IsPet())
4815 {
4816 switch (m_spellInfo->PowerType)
4817 {
4818 case POWER_HEALTH:
4819 break;
4820 case POWER_RUNE:
4821 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4822 break;
4823 default:
4824 if (m_powerCost != 0)
4825 {
4826 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4827 }
4828 break;
4829 }
4830 }
4831
4832 if ((m_caster->IsPlayer())
4836 {
4837 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4838 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4839 }
4840
4842 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4843
4844 if (m_targets.HasTraj())
4845 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4846
4848 castFlags |= CAST_FLAG_NO_GCD;
4849
4850 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4851 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4852 {
4853 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4854 {
4855 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4856 {
4857 realCasterGUID = casterGameobject->GetPackGUID();
4858 }
4859 }
4860 }
4861
4862 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4863
4864 if (m_CastItem)
4865 data << m_CastItem->GetPackGUID();
4866 else
4867 data << realCasterGUID;
4868
4869 data << realCasterGUID;
4870 data << uint8(m_cast_count); // pending spell cast?
4871 data << uint32(m_spellInfo->Id); // spellId
4872 data << uint32(castFlags); // cast flags
4873 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4874
4875 WriteSpellGoTargets(&data);
4876
4877 m_targets.Write(data);
4878
4879 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4881
4882 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4883 {
4884 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4885 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4886 if (Player* player = m_caster->ToPlayer())
4887 {
4888 uint8 runeMaskInitial = m_runesState;
4889 uint8 runeMaskAfterCast = player->GetRunesState();
4890 data << uint8(runeMaskInitial); // runes state before
4891 data << uint8(runeMaskAfterCast); // runes state after
4892 for (uint8 i = 0; i < MAX_RUNES; ++i)
4893 {
4894 uint8 mask = (1 << i);
4895 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4896 {
4897 // float casts ensure the division is performed on floats as we need float result
4898 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4899 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4900 }
4901 }
4902 }
4903 }
4904 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4905 {
4906 data << m_targets.GetElevation();
4908 }
4909
4910 if (castFlags & CAST_FLAG_PROJECTILE)
4911 WriteAmmoToPacket(&data);
4912
4913 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4914 {
4915 data << uint32(0);
4916 data << uint32(0);
4917 }
4918
4920 {
4921 data << uint8(0);
4922 }
4923
4924 m_caster->SendMessageToSet(&data, true);
4925}
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition: SpellInfo.h:195
@ CAST_FLAG_VISUAL_CHAIN
Definition: Spell.h:63
@ CAST_FLAG_ADJUST_MISSILE
Definition: Spell.h:61
@ CAST_FLAG_UNKNOWN_9
Definition: Spell.h:52
@ CAST_FLAG_NO_GCD
Definition: Spell.h:62
@ CAST_FLAG_PROJECTILE
Definition: Spell.h:49
@ CAST_FLAG_POWER_LEFT_SELF
Definition: Spell.h:55
@ CAST_FLAG_RUNE_LIST
Definition: Spell.h:65
@ CAST_FLAG_PENDING
Definition: Spell.h:44
@ SPELL_EFFECT_ACTIVATE_RUNE
Definition: SharedDefines.h:924
@ SPELL_ATTR0_USES_RANGED_SLOT
Definition: SharedDefines.h:383
@ SMSG_SPELL_GO
Definition: Opcodes.h:336
Definition: ObjectGuid.h:263
void Write(ByteBuffer &data)
Definition: Spell.cpp:180
void WriteSpellGoTargets(WorldPacket *data)
Writes miss and hit targets for a SMSG_SPELL_GO packet.
Definition: Spell.cpp:5012
void WriteAmmoToPacket(WorldPacket *data)
Definition: Spell.cpp:4927
bool IsNeedSendToClient(bool go) const
Definition: Spell.cpp:8090
SpellCastTimesEntry const * CastTimeEntry
Definition: SpellInfo.h:347
int32 CastTime
Definition: DBCStructure.h:1759

References CAST_FLAG_ADJUST_MISSILE, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_RUNE_LIST, CAST_FLAG_UNKNOWN_9, CAST_FLAG_VISUAL_CHAIN, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, SpellCastTargets::GetElevation(), GameTime::GetGameTimeMS(), Object::GetPackGUID(), Unit::GetPower(), SpellCastTargets::GetTargetMask(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), Unit::IsClass(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_delayMoment, m_delayTrajectory, m_powerCost, m_runesState, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_RUNES, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, WorldObject::SendMessageToSet(), SMSG_SPELL_GO, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_EFFECT_ACTIVATE_RUNE, SpellInfo::StartRecoveryTime, TARGET_FLAG_DEST_LOCATION, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), WriteAmmoToPacket(), and WriteSpellGoTargets().

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4717{
4718 if (!IsNeedSendToClient(false))
4719 return;
4720
4721 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4722
4723 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4724
4726 castFlags |= CAST_FLAG_PENDING;
4727
4729 castFlags |= CAST_FLAG_PROJECTILE;
4730
4731 if (m_caster->IsPlayer() || m_caster->IsPet())
4732 {
4733 switch (m_spellInfo->PowerType)
4734 {
4735 case POWER_HEALTH:
4736 break;
4737 case POWER_RUNE:
4738 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4739 break;
4740 default:
4741 if (m_powerCost != 0)
4742 {
4743 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4744 }
4745 break;
4746 }
4747 }
4748
4750 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4751
4752 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4753 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4754 {
4755 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4756 {
4757 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4758 {
4759 realCasterGUID = casterGameobject->GetPackGUID();
4760 }
4761 }
4762 }
4763
4764 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4765 if (m_CastItem)
4766 data << m_CastItem->GetPackGUID();
4767 else
4768 data << realCasterGUID;
4769
4770 data << realCasterGUID;
4771 data << uint8(m_cast_count); // pending spell cast?
4772 data << uint32(m_spellInfo->Id); // spellId
4773 data << uint32(castFlags); // cast flags
4774 data << int32(m_timer); // delay?
4775
4776 m_targets.Write(data);
4777
4778 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4780
4781 if (castFlags & CAST_FLAG_PROJECTILE)
4782 WriteAmmoToPacket(&data);
4783
4784 if (castFlags & CAST_FLAG_UNKNOWN_23)
4785 {
4786 data << uint32(0);
4787 data << uint32(0);
4788 }
4789
4790 m_caster->SendMessageToSet(&data, true);
4791
4794}
@ CAST_FLAG_UNKNOWN_23
Definition: Spell.h:66
@ CAST_FLAG_HAS_TRAJECTORY
Definition: Spell.h:45
@ SMSG_SPELL_START
Definition: Opcodes.h:335

References CAST_FLAG_HAS_TRAJECTORY, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_UNKNOWN_23, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, WorldObject::FindMap(), Object::GetGUID(), Object::GetPackGUID(), Unit::GetPower(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_timer, m_triggeredByAuraSpell, Player::NeedSendSpectatorData(), POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), SMSG_SPELL_START, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), and WriteAmmoToPacket().

Referenced by prepare().

◆ SetAutoRepeat()

void Spell::SetAutoRepeat ( bool  rep)
inline
549{ m_autoRepeat = rep; }

References m_autoRepeat.

◆ SetDelayStart()

void Spell::SetDelayStart ( uint64  m_time)
inline
563{ m_delayStart = m_time; }

References m_delayStart.

Referenced by _cast(), and SpellEvent::Execute().

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
561{m_executedCurrently = yes;}

References m_executedCurrently.

Referenced by _cast(), and Unit::AttackerStateUpdate().

◆ SetReferencedFromCurrent()

void Spell::SetReferencedFromCurrent ( bool  yes)
inline

◆ SetSpellValue()

void Spell::SetSpellValue ( SpellValueMod  mod,
int32  value 
)
8432{
8433 switch (mod)
8434 {
8436 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8437 break;
8439 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8440 break;
8442 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8443 break;
8445 m_spellValue->RadiusMod = (float)value / 10000;
8446 break;
8449 break;
8452 break;
8454 m_spellValue->AuraDuration = value;
8455 break;
8457 m_spellValue->ForcedCritResult = (bool)value;
8458 break;
8459 }
8460}
@ SPELLVALUE_AURA_STACK
Definition: SpellDefines.h:119
@ SPELLVALUE_AURA_DURATION
Definition: SpellDefines.h:120
@ SPELLVALUE_RADIUS_MOD
Definition: SpellDefines.h:117
@ SPELLVALUE_MAX_TARGETS
Definition: SpellDefines.h:118
@ SPELLVALUE_FORCED_CRIT_RESULT
Definition: SpellDefines.h:121
bool ForcedCritResult
Definition: Spell.h:218

References SpellValue::AuraDuration, SpellValue::AuraStackAmount, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, SpellInfo::Effects, SpellValue::ForcedCritResult, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, SPELLVALUE_AURA_DURATION, SPELLVALUE_AURA_STACK, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, SPELLVALUE_FORCED_CRIT_RESULT, SPELLVALUE_MAX_TARGETS, and SPELLVALUE_RADIUS_MOD.

Referenced by Player::CastItemUseSpell(), Unit::CastSpell(), and spell_gen_mod_radius_by_caster_scale::PrepareSpellScript().

◆ setState()

void Spell::setState ( uint32  state)
inline
483{ m_spellState = state; }

References m_spellState.

◆ SummonGuardian()

void Spell::SummonGuardian ( uint32  i,
uint32  entry,
SummonPropertiesEntry const *  properties,
uint32  numSummons,
bool  personalSpawn 
)
protected
5933{
5934 Unit* caster = m_originalCaster;
5935 if (!caster)
5936 return;
5937
5938 if (caster->IsTotem())
5939 caster = caster->ToTotem()->GetOwner();
5940
5941 // in another case summon new
5942 uint8 summonLevel = caster->GetLevel();
5943
5944 // level of pet summoned using engineering item based at engineering skill level
5945 if (m_CastItem && caster->IsPlayer())
5946 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5947 {
5948 // xinef: few special cases
5949 if (proto->RequiredSkill == SKILL_ENGINEERING)
5950 {
5951 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5952 summonLevel = skill202 / 5;
5953 }
5954
5955 switch (m_spellInfo->Id)
5956 {
5957 // Dragon's Call
5958 case 13049:
5959 summonLevel = 55;
5960 break;
5961
5962 // Cleansed Timberling Heart: Summon Timberling
5963 case 5666:
5964 summonLevel = 7;
5965 break;
5966
5967 // Glowing Cat Figurine: Summon Ghost Saber
5968 case 6084:
5969 // minLevel 19, maxLevel 20
5970 summonLevel = 20;
5971 break;
5972
5973 // Spiked Collar: Summon Felhunter
5974 case 8176:
5975 summonLevel = 30;
5976 break;
5977
5978 // Dog Whistle: Summon Tracking Hound
5979 case 9515:
5980 summonLevel = 30;
5981 break;
5982
5983 // Barov Peasant Caller: Death by Peasant
5984 case 18307:
5985 case 18308:
5986 summonLevel = 60;
5987 break;
5988
5989 // Thornling Seed: Plant Thornling
5990 case 22792:
5991 summonLevel = 60;
5992 break;
5993
5994 // Cannonball Runner: Summon Crimson Cannon
5995 case 6251:
5996 summonLevel = 61;
5997 break;
5998 }
5999 }
6000
6001 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6002
6003 float radius = 5.0f;
6004 int32 duration = m_spellInfo->GetDuration();
6005
6006 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6007 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6008
6009 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6010 Map* map = caster->GetMap();
6011 TempSummon* summon = nullptr;
6012
6013 uint32 currMinionsCount = m_caster->m_Controlled.size();
6014 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6015
6016 for (uint32 count = 0; count < numGuardians; ++count)
6017 {
6018 Position pos;
6019
6020 // xinef: do not use precalculated position for effect summon pet in this function
6021 // it means it was cast by NPC and should have its position overridden unless the
6022 // target position is specified in the DB AND the effect has no or zero radius
6023 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6024 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6025 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6026 {
6027 pos = *destTarget;
6028 }
6029 else
6030 {
6031 // randomize position
6032 pos = m_caster->GetRandomPoint(*destTarget, radius);
6033 }
6034
6035 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6036 if (!summon)
6037 return;
6038
6039 // xinef: set calculated level
6040 summon->SetLevel(summonLevel);
6041
6042 // if summonLevel changed, set stats for calculated level
6043 if (summonLevel != caster->GetLevel())
6044 {
6045 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6046 }
6047
6048 // xinef: if we have more than one guardian, change follow angle
6049 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6050 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6051 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6052 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6053
6054 // xinef: move this here, some auras are added in initstatsforlevel!
6055 if (!summon->IsInCombat() && !summon->IsTrigger())
6056 {
6057 // summon->AI()->EnterEvadeMode();
6058 summon->GetMotionMaster()->Clear(false);
6060 }
6061
6062 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6063 summon->SetFaction(caster->GetFaction());
6064
6066 }
6067}
@ CONFIG_MAX_PLAYER_LEVEL
Definition: IWorld.h:240
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition: IWorld.h:290
@ SKILL_ENGINEERING
Definition: SharedDefines.h:2923
bool IsTrigger() const
Definition: Creature.h:78
Definition: TemporarySummon.h:76
Unit * GetOwner() const
Definition: TemporarySummon.cpp:385
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition: Unit.cpp:15414

References SummonPropertiesEntry::Category, MotionMaster::Clear(), CONFIG_MAX_PLAYER_LEVEL, CONFIG_WORLD_BOSS_LEVEL_DIFF, destTarget, ExecuteLogEffectSummonObject(), Position::GetAbsoluteAngle(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetMotionMaster(), Minion::GetOwner(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetRandomPoint(), Player::GetSkillValue(), GetSpellInfo(), Unit::GetSpellModOwner(), Item::GetTemplate(), Unit::HasUnitTypeMask(), SpellInfo::Id, Unit::IsInCombat(), Object::IsPlayer(), Unit::IsTotem(), Creature::IsTrigger(), m_caster, m_CastItem, Unit::m_Controlled, m_originalCaster, m_spellInfo, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), PET_FOLLOW_DIST, Unit::SetFaction(), Unit::SetLevel(), SKILL_ENGINEERING, SPELL_EFFECT_SUMMON_PET, SPELLMOD_DURATION, SUMMON_CATEGORY_ALLY, Map::SummonCreature(), sWorld, TARGET_DEST_DB, Object::ToPlayer(), Unit::ToTotem(), and UNIT_MASK_MINION.

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5379{
5381 {
5383
5384 // wands don't have ammo
5385 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5386 return;
5387
5388 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5389 {
5390 if (pItem->GetMaxStackCount() == 1)
5391 {
5392 // decrease durability for non-stackable throw weapon
5394 }
5395 else
5396 {
5397 // decrease items amount for stackable throw weapon
5398 uint32 count = 1;
5399 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5400 }
5401 }
5403 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5404 }
5405}
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:692
@ INVTYPE_THROWN
Definition: ItemTemplate.h:281
uint32 GetMaxStackCount() const
Definition: Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition: Player.cpp:4804

References Player::DestroyItemCount(), Player::DurabilityPointLossForEquipSlot(), EQUIPMENT_SLOT_RANGED, Item::GetMaxStackCount(), Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), ItemTemplate::InventoryType, INVTYPE_THROWN, Item::IsBroken(), Object::IsPlayer(), ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, ItemTemplate::SubClass, and Object::ToPlayer().

Referenced by handle_immediate(), and HandleLaunchPhase().

◆ TakeCastItem()

void Spell::TakeCastItem ( )
5252{
5253 if (!m_CastItem || !m_caster->IsPlayer())
5254 return;
5255
5256 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5258 return;
5259
5260 ItemTemplate const* proto = m_CastItem->GetTemplate();
5261
5262 if (!proto)
5263 {
5264 // This code is to avoid a crash
5265 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5266 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5267 return;
5268 }
5269
5270 bool expendable = false;
5271 bool withoutCharges = false;
5272
5273 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5274 {
5275 if (proto->Spells[i].SpellId)
5276 {
5277 // item has limited charges
5278 if (proto->Spells[i].SpellCharges)
5279 {
5280 if (proto->Spells[i].SpellCharges < 0)
5281 expendable = true;
5282
5283 int32 charges = m_CastItem->GetSpellCharges(i);
5284
5285 // item has charges left
5286 if (charges)
5287 {
5288 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5289 if (proto->Stackable == 1)
5290 m_CastItem->SetSpellCharges(i, charges);
5292 }
5293
5294 // all charges used
5295 withoutCharges = (charges == 0);
5296 }
5297 }
5298 }
5299
5300 if (expendable && withoutCharges)
5301 {
5302 uint32 count = 1;
5303 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5304
5305 // prevent crash at access to deleted m_targets.GetItemTarget
5307 m_targets.SetItemTarget(nullptr);
5308
5309 m_CastItem = nullptr;
5311 }
5312}
void SetSpellCharges(uint8 index, int32 value)
Definition: Item.h:318
int32 Stackable
Definition: ItemTemplate.h:645

References ObjectGuid::Clear(), Player::DestroyItemCount(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetSpellCharges(), Item::GetTemplate(), HasTriggeredCastFlag(), Object::IsPlayer(), ITEM_CHANGED, LOG_ERROR, m_caster, m_CastItem, m_castItemGUID, m_targets, MAX_ITEM_PROTO_SPELLS, SpellCastTargets::SetItemTarget(), Item::SetSpellCharges(), Item::SetState(), _Spell::SpellCharges, _Spell::SpellId, ItemTemplate::Spells, ItemTemplate::Stackable, Object::ToPlayer(), ObjectGuid::ToString(), and TRIGGERED_IGNORE_CAST_ITEM.

Referenced by _cast(), and handle_immediate().

◆ TakePower()

void Spell::TakePower ( )
5315{
5317 return;
5318
5319 //Don't take power if the spell is cast while .cheat power is enabled.
5320 if (m_caster->IsPlayer())
5322 return;
5323
5325 bool hit = true;
5326 if (m_caster->IsPlayer())
5327 {
5329 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5330 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5331 if (ihit->targetGUID == targetGUID)
5332 {
5333 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5334 {
5335 hit = false;
5336 //lower spell cost on fail (by talent aura)
5337 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5338 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5339 }
5340 break;
5341 }
5342 }
5343
5344 if (PowerType == POWER_RUNE)
5345 {
5346 TakeRunePower(hit);
5347 return;
5348 }
5349
5350 if (!m_powerCost)
5351 return;
5352
5353 // health as power used
5354 if (PowerType == POWER_HEALTH)
5355 {
5357 return;
5358 }
5359
5360 if (PowerType >= MAX_POWERS)
5361 {
5362 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5363 return;
5364 }
5365
5366 if (hit)
5368 else
5370
5371 // Set the five second timer
5372 if (PowerType == POWER_MANA && m_powerCost > 0)
5373 {
5375 }
5376}
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition: SpellDefines.h:107
@ SPELL_MISS_ABSORB
Definition: SharedDefines.h:1529
int32 ModifyHealth(int32 val)
Definition: Unit.cpp:14047
void SetLastManaUse(uint32 spellCastTime)
Definition: Unit.h:1570
void TakeRunePower(bool didHit)
Definition: Spell.cpp:5461

References CHEAT_POWER, Player::GetCommandStatus(), GameTime::GetGameTimeMS(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTargetGUID(), SpellInfo::Id, irand(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, MAX_POWERS, Unit::ModifyHealth(), Unit::ModifyPower(), POWER_ENERGY, POWER_HEALTH, POWER_MANA, POWER_RAGE, POWER_RUNE, POWER_RUNIC_POWER, SpellInfo::PowerType, Unit::SetLastManaUse(), SPELL_MISS_ABSORB, SPELL_MISS_BLOCK, SPELL_MISS_NONE, SPELL_MISS_REFLECT, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, TakeRunePower(), and Object::ToPlayer().

Referenced by _cast().

◆ TakeReagents()

void Spell::TakeReagents ( )
5531{
5532 if (!m_caster->IsPlayer())
5533 return;
5534
5535 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5536
5537 // do not take reagents for these item casts
5538 if (castItemTemplate && castItemTemplate->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
5539 return;
5540
5541 Player* p_caster = m_caster->ToPlayer();
5542 if (p_caster->CanNoReagentCast(m_spellInfo))
5543 return;
5544
5545 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5546 {
5547 if (m_spellInfo->Reagent[x] <= 0)
5548 continue;
5549
5550 uint32 itemid = m_spellInfo->Reagent[x];
5551 uint32 itemcount = m_spellInfo->ReagentCount[x];
5552
5553 // if CastItem is also spell reagent
5554 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5555 {
5556 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5557 {
5558 // CastItem will be used up and does not count as reagent
5559 int32 charges = m_CastItem->GetSpellCharges(s);
5560 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5561 {
5562 ++itemcount;
5563 break;
5564 }
5565 }
5566
5567 m_CastItem = nullptr;
5569 }
5570
5571 // if GetItemTarget is also spell reagent
5572 if (m_targets.GetItemTargetEntry() == itemid)
5573 m_targets.SetItemTarget(nullptr);
5574
5575 p_caster->DestroyItemCount(itemid, itemcount, true);
5576 }
5577}
uint32 ItemId
Definition: ItemTemplate.h:620

References Player::CanNoReagentCast(), ObjectGuid::Clear(), Player::DestroyItemCount(), SpellCastTargets::GetItemTargetEntry(), Item::GetSpellCharges(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_NO_REAGENT_COST, ItemTemplate::ItemId, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, MAX_ITEM_PROTO_SPELLS, MAX_SPELL_REAGENTS, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellCastTargets::SetItemTarget(), _Spell::SpellCharges, ItemTemplate::Spells, and Object::ToPlayer().

Referenced by _cast().

◆ TakeRunePower()

void Spell::TakeRunePower ( bool  didHit)
5462{
5464 return;
5465
5466 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5467 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5468 return;
5469
5470 Player* player = m_caster->ToPlayer();
5471 m_runesState = player->GetRunesState(); // store previous state
5472
5473 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5474
5475 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5476 {
5477 runeCost[i] = runeCostData->RuneCost[i];
5478 if (Player* modOwner = m_caster->GetSpellModOwner())
5479 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5480 }
5481
5482 runeCost[RUNE_DEATH] = 0; // calculated later
5483
5484 for (uint32 i = 0; i < MAX_RUNES; ++i)
5485 {
5486 RuneType rune = player->GetCurrentRune(i);
5487 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5488 {
5489 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5490 player->SetLastUsedRune(rune);
5491 runeCost[rune]--;
5492 }
5493 }
5494
5495 // Xinef: firstly consume death runes of base type
5496 // Xinef: in second loop consume all available
5497 for (uint8 loop = 0; loop < 2; ++loop)
5498 {
5499 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5500 if (runeCost[RUNE_DEATH] > 0)
5501 {
5502 for (uint8 i = 0; i < MAX_RUNES; ++i)
5503 {
5504 RuneType rune = player->GetCurrentRune(i);
5505 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5506 {
5507 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5508 player->SetLastUsedRune(rune);
5509 runeCost[rune]--;
5510 if (!loop)
5511 runeCost[player->GetBaseRune(i)]--;
5512
5513 // keep Death Rune type if missed
5514 if (didHit)
5515 player->RestoreBaseRune(i);
5516
5517 if (runeCost[RUNE_DEATH] == 0)
5518 break;
5519 }
5520 }
5521 }
5522 }
5523
5524 // you can gain some runic power when use runes
5525 if (didHit)
5526 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5527 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5528}
@ RATE_POWER_RUNICPOWER_INCOME
Definition: IWorld.h:437
@ RUNE_UNHOLY
Definition: Player.h:410
@ RUNE_BLOOD
Definition: Player.h:409
@ RUNE_MISS_COOLDOWN
Definition: Player.h:404
void SetLastUsedRune(RuneType type)
Definition: Player.h:2495
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition: Player.cpp:13371
void RestoreBaseRune(uint8 index)
Definition: Player.cpp:13400
bool NoRunicPowerGain() const
Definition: DBCStructure.h:1810
uint32 runePowerGain
Definition: DBCStructure.h:1807

References CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneBaseCooldown(), Player::GetRuneCooldown(), Player::GetRunesState(), Unit::GetSpellModOwner(), SpellInfo::Id, Unit::IsClass(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, Unit::ModifyPower(), SpellRuneCostEntry::NoRuneCost(), SpellRuneCostEntry::NoRunicPowerGain(), NUM_RUNE_TYPES, POWER_RUNIC_POWER, RATE_POWER_RUNICPOWER_INCOME, Player::RestoreBaseRune(), RUNE_BLOOD, RUNE_DEATH, RUNE_FROST, RUNE_MISS_COOLDOWN, RUNE_UNHOLY, SpellRuneCostEntry::RuneCost, SpellInfo::RuneCostID, SpellRuneCostEntry::runePowerGain, Player::SetLastUsedRune(), Player::SetRuneCooldown(), SPELLMOD_COST, sSpellRuneCostStore, sWorld, and Object::ToPlayer().

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
8840{
8842 if (!gcd)
8843 {
8844 // Xinef: fix for charmed pet spells with no cooldown info
8846 gcd = MIN_GCD;
8847 else
8848 return;
8849 }
8850
8851 if (m_caster->IsPlayer())
8853 return;
8854
8855 // Global cooldown can't leave range 1..1.5 secs
8856 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8857 // but as tests show are not affected by any spell mods.
8859 {
8860 // gcd modifier auras are applied only to own spells and only players have such mods
8861 if (m_caster->IsPlayer())
8863
8864 // Apply haste rating
8867 {
8868 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8869 }
8870
8871 if (gcd < MIN_GCD)
8872 gcd = MIN_GCD;
8873 else if (gcd > MAX_GCD)
8874 gcd = MAX_GCD;
8875 }
8876
8877 // Only players or controlled units have global cooldown
8878 if (m_caster->GetCharmInfo())
8880 else if (m_caster->IsPlayer())
8882}
@ MIN_GCD
Definition: Spell.cpp:8824
@ MAX_GCD
Definition: Spell.cpp:8825
@ SPELLMOD_GLOBAL_COOLDOWN
Definition: SpellDefines.h:98
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition: CharmInfo.cpp:410

References GlobalCooldownMgr::AddGlobalCooldown(), Player::ApplySpellMod(), SpellInfo::CategoryRecoveryTime, CHEAT_COOLDOWN, SpellInfo::DmgClass, Unit::GetCharmInfo(), Player::GetCommandStatus(), Object::GetFloatValue(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), SpellInfo::HasAttribute(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, MAX_GCD, MIN_GCD, SpellInfo::RecoveryTime, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLMOD_GLOBAL_COOLDOWN, SpellInfo::StartRecoveryCategory, SpellInfo::StartRecoveryTime, Object::ToPlayer(), and UNIT_MOD_CAST_SPEED.

Referenced by prepare().

◆ update()

void Spell::update ( uint32  difftime)
4401{
4402 // update pointers based at it's GUIDs
4403 if (!UpdatePointers())
4404 {
4405 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4406 cancel();
4407 return;
4408 }
4409
4411 {
4412 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4413 cancel();
4414 return;
4415 }
4416
4417 // check if the player caster has moved before the spell finished
4418 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4419 if ((m_caster->IsPlayer() && m_timer != 0) &&
4422 {
4423 // don't cancel for melee, autorepeat, triggered and instant spells
4425 cancel(true);
4426 }
4427
4428 switch (m_spellState)
4429 {
4431 {
4432 if (m_timer > 0)
4433 {
4434 if (difftime >= (uint32)m_timer)
4435 m_timer = 0;
4436 else
4437 m_timer -= difftime;
4438 }
4439
4440 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4441 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4442 cast(!m_casttime);
4443 break;
4444 }
4446 {
4447 if (m_timer)
4448 {
4449 if (m_timer > 0)
4450 {
4451 if (difftime >= (uint32)m_timer)
4452 m_timer = 0;
4453 else
4454 m_timer -= difftime;
4455 }
4456 }
4457
4458 if (m_timer == 0)
4459 {
4461
4462 finish();
4463 }
4464 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4465 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4466 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4467 // Xinef: so the aura can be removed in different updates for all units
4468 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4469 {
4470 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4472 finish();
4473 }
4474 break;
4475 }
4476 default:
4477 break;
4478 }
4479}
bool UpdateChanneledTargetList()
Definition: Spell.cpp:3388

References cancel(), cast(), SpellInfo::Effects, finish(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::GetUnitTargetGUID(), Unit::HasUnitMovementFlag(), SpellInfo::Id, SpellInfo::InterruptFlags, IsAutoRepeat(), Unit::isMoving(), IsNextMeleeSwingSpell(), Object::IsPlayer(), IsTriggered(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_spellState, m_targets, m_timer, MOVEMENTFLAG_FALLING_FAR, SendChannelUpdate(), SPELL_EFFECT_STUCK, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, UpdateChanneledTargetList(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3389{
3390 // Not need check return true
3392 return true;
3393
3394 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3395 uint8 channelAuraMask = 0;
3396 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3398 channelAuraMask |= 1 << i;
3399
3400 channelAuraMask &= channelTargetEffectMask;
3401
3402 float range = 0;
3403 if (channelAuraMask)
3404 {
3406 if (range == 0)
3407 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3408 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3409 {
3410 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3411 break;
3412 }
3413
3414 if (Player* modOwner = m_caster->GetSpellModOwner())
3415 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3416
3417 // xinef: add little tolerance level
3418 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3419 }
3420
3421 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3422 {
3423 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3424 {
3425 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3426
3427 if (!unit)
3428 continue;
3429
3430 if (IsValidDeadOrAliveTarget(unit))
3431 {
3432 if (channelAuraMask & ihit->effectMask)
3433 {
3435 {
3436 if (m_caster != unit)
3437 {
3438 if (!m_caster->IsWithinDistInMap(unit, range))
3439 {
3440 ihit->effectMask &= ~aurApp->GetEffectMask();
3441 unit->RemoveAura(aurApp);
3442 continue;
3443 }
3444 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3447 }
3448 }
3449 else // aura is dispelled
3450 continue;
3451 }
3452
3453 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3454 }
3455 }
3456 }
3457
3458 // Xinef: not all effects are covered, remove applications from all targets
3459 if (channelTargetEffectMask != 0)
3460 {
3461 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3462 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3463 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3464 if (IsValidDeadOrAliveTarget(unit))
3466 {
3467 ihit->effectMask &= ~aurApp->GetEffectMask();
3468 unit->RemoveAura(aurApp);
3469 }
3470 }
3471
3472 // is all effects from m_needAliveTargetMask have alive targets
3473 return channelTargetEffectMask == 0;
3474}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition: SharedDefines.h:433
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1321
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition: Unit.cpp:5532
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition: Unit.cpp:20030
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition: Spell.cpp:8222

References EFFECT_0, EFFECT_2, SpellInfo::Effects, Position::GetAngle(), Unit::GetAuraApplication(), Object::GetGUID(), SpellInfo::GetMaxRange(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsPositive(), IsValidDeadOrAliveTarget(), WorldObject::IsWithinDistInMap(), m_caster, m_channelTargetEffectMask, m_originalCasterGUID, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::RemoveAura(), SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL, SPELL_EFFECT_APPLY_AURA, SPELL_MISS_NONE, SPELLMOD_RANGE, and Unit::UpdateOrientation().

Referenced by update().

◆ UpdatePointers()

bool Spell::UpdatePointers ( )
7861{
7864 else
7865 {
7868 m_originalCaster = nullptr;
7869 }
7870
7872 {
7874 // cast item not found, somehow the item is no longer where we expected
7875 if (!m_CastItem)
7876 return false;
7877 }
7878 else
7879 m_CastItem = nullptr;
7880
7882
7883 // further actions done only for dest targets
7884 if (!m_targets.HasDst())
7885 return true;
7886
7887 // cache last transport
7888 WorldObject* transport = nullptr;
7889
7890 // update effect destinations (in case of moved transport dest target)
7891 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7892 {
7893 SpellDestination& dest = m_destTargets[effIndex];
7894 if (!dest._transportGUID)
7895 continue;
7896
7897 if (!transport || transport->GetGUID() != dest._transportGUID)
7899
7900 if (transport)
7901 {
7902 dest._position.Relocate(transport);
7904 }
7905 }
7906
7907 return true;
7908}
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:118
void RelocateOffset(const Position &offset)
Definition: Position.cpp:58
Position _transportOffset
Definition: Spell.h:105
ObjectGuid _transportGUID
Definition: Spell.h:104
void Update(Unit *caster)
Definition: Spell.cpp:480

References SpellDestination::_position, SpellDestination::_transportGUID, SpellDestination::_transportOffset, Object::GetGUID(), Player::GetItemByGuid(), ObjectAccessor::GetUnit(), ObjectAccessor::GetWorldObject(), SpellCastTargets::HasDst(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_CastItem, m_castItemGUID, m_destTargets, m_originalCaster, m_originalCasterGUID, m_targets, MAX_SPELL_EFFECTS, Position::Relocate(), Position::RelocateOffset(), Object::ToPlayer(), and SpellCastTargets::Update().

Referenced by _cast(), handle_delayed(), and update().

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket data)
4928{
4929 uint32 ammoInventoryType = 0;
4930 uint32 ammoDisplayID = 0;
4931
4932 if (m_caster->IsPlayer())
4933 {
4935 if (pItem)
4936 {
4937 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4938 if (ammoInventoryType == INVTYPE_THROWN)
4939 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4940 else
4941 {
4943 if (ammoID)
4944 {
4945 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4946 if (pProto)
4947 {
4948 ammoDisplayID = pProto->DisplayInfoID;
4949 ammoInventoryType = pProto->InventoryType;
4950 }
4951 }
4952 else if (m_caster->HasAura(46699)) // Requires No Ammo
4953 {
4954 ammoDisplayID = 5996; // normal arrow
4955 ammoInventoryType = INVTYPE_AMMO;
4956 }
4957 }
4958 }
4959 }
4960 else
4961 {
4962 uint32 nonRangedAmmoDisplayID = 0;
4963 uint32 nonRangedAmmoInventoryType = 0;
4964 for (uint8 i = 0; i < 3; ++i)
4965 {
4967 {
4968 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4969 {
4970 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
4971 {
4972 switch (itemEntry->SubclassID)
4973 {
4975 ammoDisplayID = itemEntry->DisplayInfoID;
4976 ammoInventoryType = itemEntry->InventoryType;
4977 break;
4980 ammoDisplayID = 5996; // is this need fixing?
4981 ammoInventoryType = INVTYPE_AMMO;
4982 break;
4984 ammoDisplayID = 5998; // is this need fixing?
4985 ammoInventoryType = INVTYPE_AMMO;
4986 break;
4987 default:
4988 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4989 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4990 break;
4991 }
4992
4993 if (ammoDisplayID)
4994 break;
4995 }
4996 }
4997 }
4998 }
4999
5000 if (!ammoDisplayID && !ammoInventoryType)
5001 {
5002 ammoDisplayID = nonRangedAmmoDisplayID;
5003 ammoInventoryType = nonRangedAmmoInventoryType;
5004 }
5005 }
5006
5007 *data << uint32(ammoDisplayID);
5008 *data << uint32(ammoInventoryType);
5009}
DBCStorage< ItemEntry > sItemStore(Itemfmt)
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition: UpdateFields.h:116
@ INVTYPE_AMMO
Definition: ItemTemplate.h:280
uint32 DisplayInfoID
Definition: ItemTemplate.h:625
Definition: DBCStructure.h:1139

References ItemTemplate::DisplayInfoID, Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), Unit::HasAura(), ItemTemplate::InventoryType, INVTYPE_AMMO, INVTYPE_THROWN, Object::IsPlayer(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, sItemStore, sObjectMgr, Object::ToPlayer(), and UNIT_VIRTUAL_ITEM_SLOT_ID.

Referenced by SendSpellGo(), and SendSpellStart().

◆ WriteCastResultInfo()

void Spell::WriteCastResultInfo ( WorldPacket data,
Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError 
)
static
4564{
4565 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4566 data << uint32(spellInfo->Id);
4567 data << uint8(result); // problem
4568 switch (result)
4569 {
4571 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4572 break;
4573 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4574 // hardcode areas limitation case
4575 switch (spellInfo->Id)
4576 {
4577 case 41617: // Cenarion Mana Salve
4578 case 41619: // Cenarion Healing Salve
4579 data << uint32(3905);
4580 break;
4581 case 41618: // Bottled Nethergon Energy
4582 case 41620: // Bottled Nethergon Vapor
4583 data << uint32(3842);
4584 break;
4585 case 45373: // Bloodberry Elixir
4586 data << uint32(4075);
4587 break;
4588 default: // default case (don't must be)
4589 data << uint32(0);
4590 break;
4591 }
4592 break;
4594 if (spellInfo->Totem[0])
4595 data << uint32(spellInfo->Totem[0]);
4596 if (spellInfo->Totem[1])
4597 data << uint32(spellInfo->Totem[1]);
4598 break;
4600 if (spellInfo->TotemCategory[0])
4601 data << uint32(spellInfo->TotemCategory[0]);
4602 if (spellInfo->TotemCategory[1])
4603 data << uint32(spellInfo->TotemCategory[1]);
4604 break;
4608 data << uint32(spellInfo->EquippedItemClass);
4609 data << uint32(spellInfo->EquippedItemSubClassMask);
4610 break;
4612 {
4613 uint32 item = 0;
4614 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4615 if (spellInfo->Effects[eff].ItemType)
4616 item = spellInfo->Effects[eff].ItemType;
4617 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4618 if (proto && proto->ItemLimitCategory)
4619 data << uint32(proto->ItemLimitCategory);
4620 break;
4621 }
4623 data << uint32(customError);
4624 break;
4626 {
4627 uint32 missingItem = 0;
4628 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4629 {
4630 if (spellInfo->Reagent[i] <= 0)
4631 continue;
4632
4633 uint32 itemid = spellInfo->Reagent[i];
4634 uint32 itemcount = spellInfo->ReagentCount[i];
4635
4636 if (!caster->HasItemCount(itemid, itemcount))
4637 {
4638 missingItem = itemid;
4639 break;
4640 }
4641 }
4642
4643 data << uint32(missingItem); // first missing item
4644 break;
4645 }
4647 data << uint32(spellInfo->Mechanic);
4648 break;
4650 data << uint32(spellInfo->EquippedItemSubClassMask);
4651 break;
4653 data << uint32(0); // Item entry
4654 data << uint32(0); // Count
4655 break;
4657 data << uint32(0); // SkillLine.dbc Id
4658 data << uint32(0); // Amount
4659 break;
4661 data << uint32(0); // Skill level
4662 break;
4663 default:
4664 break;
4665 }
4666}
@ SPELL_FAILED_NEED_EXOTIC_AMMO
Definition: SharedDefines.h:1003
@ SPELL_FAILED_FISHING_TOO_LOW
Definition: SharedDefines.h:1130
@ SPELL_FAILED_MIN_SKILL
Definition: SharedDefines.h:1099
@ SPELL_FAILED_PREVENTED_BY_MECHANIC
Definition: SharedDefines.h:1096
@ SPELL_FAILED_REQUIRES_AREA
Definition: SharedDefines.h:1050

References SpellInfo::Effects, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::HasItemCount(), SpellInfo::Id, ItemTemplate::ItemLimitCategory, MAX_SPELL_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::Mechanic, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellInfo::RequiresSpellFocus, sObjectMgr, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_FISHING_TOO_LOW, SPELL_FAILED_MIN_SKILL, SPELL_FAILED_NEED_EXOTIC_AMMO, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_PREVENTED_BY_MECHANIC, SPELL_FAILED_REAGENTS, SPELL_FAILED_REQUIRES_AREA, SPELL_FAILED_REQUIRES_SPELL_FOCUS, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, SpellInfo::Totem, and SpellInfo::TotemCategory.

Referenced by SendCastResult(), and SendPetCastResult().

◆ WriteSpellGoTargets()

void Spell::WriteSpellGoTargets ( WorldPacket data)

Writes miss and hit targets for a SMSG_SPELL_GO packet.

5013{
5014 // This function also fill data for channeled spells:
5015 // m_needAliveTargetMask req for stop channelig if one target die
5016 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5017 {
5018 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
5019 // possibly SPELL_MISS_IMMUNE2 for this??
5020 ihit->missCondition = SPELL_MISS_IMMUNE2;
5021 }
5022
5023 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
5024 // sending more than 255 targets crashes the client (since count sent would be wrong)
5025 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
5026 // target conditions but we still need to limit the number of targets sent and keeping
5027 // correct count for both hit and miss).
5028
5029 uint32 hit = 0;
5030 std::size_t hitPos = data->wpos();
5031 *data << (uint8)0; // placeholder
5032 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
5033 {
5034 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
5035 {
5036 *data << ihit->targetGUID;
5037 // Xinef: No channeled spell checked, no anything
5038 //m_channelTargetEffectMask |=ihit->effectMask;
5039 ++hit;
5040 }
5041 }
5042
5043 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
5044 {
5045 *data << ighit->targetGUID; // Always hits
5046 ++hit;
5047 }
5048
5049 uint32 miss = 0;
5050 std::size_t missPos = data->wpos();
5051 *data << (uint8)0; // placeholder
5052 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
5053 {
5054 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
5055 {
5056 *data << ihit->targetGUID;
5057 *data << uint8(ihit->missCondition);
5058 if (ihit->missCondition == SPELL_MISS_REFLECT)
5059 *data << uint8(ihit->reflectResult);
5060 ++miss;
5061 }
5062 }
5063 // Reset m_needAliveTargetMask for non channeled spell
5064 // Xinef: Why do we reset something that is not set??????
5065 //if (!m_spellInfo->IsChanneled())
5066 // m_channelTargetEffectMask = 0;
5067
5068 data->put<uint8>(hitPos, (uint8)hit);
5069 data->put<uint8>(missPos, (uint8)miss);
5070}
std::size_t wpos() const
Definition: ByteBuffer.h:330
void put(std::size_t pos, T value)
Definition: ByteBuffer.h:137

References m_UniqueGOTargetInfo, m_UniqueTargetInfo, ByteBuffer::put(), SPELL_MISS_IMMUNE2, SPELL_MISS_NONE, SPELL_MISS_REFLECT, and ByteBuffer::wpos().

Referenced by SendSpellGo().

Friends And Related Function Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

Referenced by _cast(), prepare(), and Spell().

◆ _triggeredCastFlags

TriggerCastFlags Spell::_triggeredCastFlags
protected

◆ damage

◆ destTarget

◆ effectHandleMode

SpellEffectHandleMode Spell::effectHandleMode
protected

Referenced by EffectActivateObject(), EffectActivateRune(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddFarsight(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDestroyAllTotems(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectDamage(), EffectGameObjectRepair(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectSkill(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectSpiritHeal(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), HandleEffects(), and Spell().

◆ focusObject

◆ gameObjTarget

◆ itemTarget

◆ m_appliedMods

◆ m_applyMultiplierMask

uint8 Spell::m_applyMultiplierMask
protected

◆ m_attackType

◆ m_auraScaleMask

uint8 Spell::m_auraScaleMask
protected

◆ m_autoRepeat

bool Spell::m_autoRepeat
protected

◆ m_canReflect

bool Spell::m_canReflect
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_cast_count

◆ m_caster

Unit* const Spell::m_caster
protected

Referenced by _cast(), _handle_finish_phase(), AddGOTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateSpellDamage(), cancel(), CancelGlobalCooldown(), CanOpenLock(), cast(), CheckCast(), CheckCasterAuras(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckSpellFocus(), CheckSrc(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectDestroyAllTotems(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectRepair(), EffectHeal(), EffectHealMaxHealth(), EffectHealthLeech(), EffectInstaKill(), EffectJump(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), finish(), GetCaster(), handle_delayed(), handle_immediate(), HandleLaunchPhase(), HandleThreatSpells(), HasGlobalCooldown(), InitExplicitTargets(), IsChannelActive(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), RecalculateDelayMomentForDst(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTrajTargets(), SendCastResult(), SendChannelStart(), SendChannelUpdate(), SendInterrupted(), SendLogExecute(), SendLoot(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Spell(), SummonGuardian(), TakeAmmo(), TakeCastItem(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), UpdateChanneledTargetList(), UpdatePointers(), and WriteAmmoToPacket().

◆ m_CastItem

◆ m_castItemGUID

◆ m_casttime

◆ m_channeledDuration

int32 Spell::m_channeledDuration
protected

◆ m_channelTargetEffectMask

uint8 Spell::m_channelTargetEffectMask
protected

◆ m_comboPointGain

int8 Spell::m_comboPointGain

◆ m_comboTarget

Unit* Spell::m_comboTarget

◆ m_customError

◆ m_damage

◆ m_damageMultipliers

float Spell::m_damageMultipliers[3]
protected

◆ m_delayAtDamageCount

uint8 Spell::m_delayAtDamageCount
protected

Referenced by isDelayableNoMore(), and Spell().

◆ m_delayMoment

◆ m_delayStart

uint64 Spell::m_delayStart
protected

Referenced by GetDelayStart(), SetDelayStart(), and Spell().

◆ m_delayTrajectory

uint64 Spell::m_delayTrajectory
protected

◆ m_destTargets

SpellDestination Spell::m_destTargets[MAX_SPELL_EFFECTS]
protected

◆ m_diminishGroup

DiminishingGroup Spell::m_diminishGroup
protected

◆ m_diminishLevel

DiminishingLevels Spell::m_diminishLevel
protected

◆ m_effectExecuteData

◆ m_executedCurrently

bool Spell::m_executedCurrently
protected

◆ m_glyphIndex

uint32 Spell::m_glyphIndex

◆ m_healing

◆ m_hitTriggerSpells

HitTriggerSpellList Spell::m_hitTriggerSpells
protected

◆ m_immediateHandled

bool Spell::m_immediateHandled
protected

Referenced by _cast(), handle_delayed(), and Spell().

◆ m_loadedScripts

◆ m_needComboPoints

bool Spell::m_needComboPoints
protected

◆ m_originalCaster

◆ m_originalCasterGUID

◆ m_powerCost

◆ m_preCastSpell

uint32 Spell::m_preCastSpell

◆ m_preGeneratedPath

std::unique_ptr<PathGenerator> Spell::m_preGeneratedPath
protected

Referenced by CheckCast(), and EffectCharge().

◆ m_procAttacker

uint32 Spell::m_procAttacker
protected

◆ m_procEx

uint32 Spell::m_procEx
protected

◆ m_procVictim

uint32 Spell::m_procVictim
protected

◆ m_referencedFromCurrentSpell

bool Spell::m_referencedFromCurrentSpell
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

Referenced by _cast(), _handle_finish_phase(), _handle_immediate_phase(), Unit::_UpdateAutoRepeatSpell(), AddGOTarget(), AddItemTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), CallScriptDestinationTargetSelectHandlers(), CallScriptEffectHandlers(), CallScriptObjectAreaTargetSelectHandlers(), CallScriptObjectTargetSelectHandlers(), CanAutoCast(), cancel(), CancelGlobalCooldown(), CanExecuteTriggersOnHit(), CanOpenLock(), CheckCast(), CheckCasterAuras(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckScriptEffectImplicitTargets(), CheckSpellFocus(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectAddHonor(), EffectApplyGlyph(), EffectBind(), EffectCastButtons(), EffectCharge(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInstaKill(), EffectInterruptCast(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectOpenLock(), EffectPersistentAA(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRemoveAura(), EffectReputation(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectStealBeneficialBuff(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectWeaponDmg(), finish(), GetCurrentContainer(), GetSearcherTypeMask(), GetSpellInfo(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), HandleEffects(), HandleLaunchPhase(), WorldSession::HandlePetCastSpellOpcode(), HandleThreatSpells(), WorldSession::HandleUpdateMissileTrajectory(), HasGlobalCooldown(), InitExplicitTargets(), IsAutoActionResetSpell(), IsNeedSendToClient(), IsNextMeleeSwingSpell(), IsValidDeadOrAliveTarget(), LoadScripts(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), Player::RemoveSpellMods(), Player::RestoreSpellMods(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendCastResult(), SendChannelStart(), SendInterrupted(), SendLogExecute(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Player::SetSpellModTakingSpell(), SetSpellValue(), Spell(), SummonGuardian(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), PetAI::UpdateAI(), UpdateChanneledTargetList(), Player::UpdatePotionCooldown(), ~Spell(), and SpellEvent::~SpellEvent().

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

Referenced by _cast(), CalculateDelayMomentForDst(), CheckCast(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckRange(), CheckSrc(), Unit::DealDamage(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), EffectBind(), EffectChargeDest(), EffectEnchantItemPerm(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectPullTowards(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerSpell(), SpellScript::GetExplTargetDest(), SpellScript::GetExplTargetGObj(), SpellScript::GetExplTargetItem(), SpellScript::GetExplTargetUnit(), SpellScript::GetExplTargetWorldObject(), handle_delayed(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), spell_vehicle_throw_passenger::HandleScript(), WorldSession::HandleUpdateMissileTrajectory(), WorldSession::HandleUpdateProjectilePosition(), InitExplicitTargets(), spell_ioc_launch::Launch(), OnSpellLaunch(), prepare(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChannelTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendChannelStart(), SendSpellGo(), SendSpellStart(), SpellScript::SetExplTargetDest(), TakeCastItem(), TakePower(), TakeReagents(), update(), and UpdatePointers().

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

Referenced by CheckCast(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectBind(), EffectCharge(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectForceCast(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectModifyThreatPercent(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSendEvent(), EffectSendTaxi(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectStealBeneficialBuff(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTriggerMissileSpell(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), SpellScript::GetHitCreature(), SpellScript::GetHitPlayer(), SpellScript::GetHitUnit(), HandleEffects(), SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitChainTargets(), SelectImplicitTrajTargets(), and Spell().